<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          用 Hypothesis 快速測試你的 Python 代碼

          共 3493字,需瀏覽 7分鐘

           ·

          2020-11-26 17:50


          介紹

          無論你使用哪種編程語言或框架,測試都非常重要。Hypothesis是 Python 的一個高級測試庫。它允許編寫測試用例時參數(shù)化,然后生成使測試失敗的簡單易懂的測試數(shù)據(jù)。可以用更少的工作在代碼中發(fā)現(xiàn)更多的bug。該測試庫覆蓋了大多數(shù)情況,并且確實可以幫助你查找代碼中的錯誤。

          這篇文章為展示了如何使用Hypothesis在Python中進(jìn)行測試,并提供了一些示例。

          我們?nèi)绾螀^(qū)分測試?

          在我們開始進(jìn)行基于屬性的測試之前,我們需要知道測試的一般區(qū)別。有不同的分組測試方法,兩種最常見的方法基于測試方法和測試級別。讓我們從大多數(shù)人已經(jīng)聽說的測試級別開始。本質(zhì)上,存在四個測試級別(盡管人們可能也知道或定義其他級別):

          • 單元測試
          • 集成測試
          • 系統(tǒng)測試
          • 端到端測試

          不同測試級別側(cè)重專注于不同的事物。單元測試側(cè)重于軟件的特定部分或功能。這可以是單個功能或功能的一部分。相反,集成測試側(cè)重于通過軟件組件的接口進(jìn)行協(xié)作。系統(tǒng)測試甚至更進(jìn)一步,可以測試整個系統(tǒng)。

          現(xiàn)在,我們將看看存在的各種各樣的測試方法。

          最常見和已知的是靜態(tài)和動態(tài)測試。所謂靜態(tài)測試(static testing)就是不實際運(yùn)行被測軟件,而只是靜態(tài)地檢查程序代碼、界面或文檔中可能存在的錯誤的過程。如果軟件或其部分實際執(zhí)行,我們稱之為動態(tài)測試。編寫單元測試和集成測試屬于動態(tài)測試。

          另一種常見的方法是盒式方法。基本上,它可以分為白盒測試和黑盒測試(以及灰盒測試作為兩者的混合)。白盒測試可驗證程序的內(nèi)部結(jié)構(gòu)或工作情況。黑盒測試與之相反,在黑盒測試中,應(yīng)用程序被視為黑盒,并且對其交互進(jìn)行測試。這意味著在不了解內(nèi)部實現(xiàn)的情況下測試功能。

          什么是基于屬性的測試?

          現(xiàn)在,我們快速了解了如何區(qū)分測試,您可能會問:什么是基于屬性的測試?

          基于屬性的測試技術(shù)( Property-based testing),是指編寫對你的代碼來說為真的邏輯語句(即“屬性”),然后使用自動化工具來生成測試輸入(一般來說,是指某種特定類型的隨機(jī)生成輸入數(shù)據(jù)),并觀察程序接受該輸入時屬性是否保持不變。如果某個輸入違反了某一條屬性,則用戶證明程序存在一處錯誤,并找到一個能夠演示該錯誤的便捷示例。

          使用Hypothesis進(jìn)行基于屬性的測試

          讓我們舉一個簡單的例子。假設(shè)您有兩個函數(shù)crement()decrement()。一個示例實現(xiàn)可能如下所示:

          #?increment_decrement.py

          def?increment(number:?int)?->?int:
          ????return?number?+?1


          def?decrement(number:?int)?->?int:
          ????return?number?-?1

          您可能會為兩者編寫單元測試代碼,如下所示:

          #?test_increment_decrement_pytest.py

          from?increment_decrement?import?decrement
          from?increment_decrement?import?increment

          def?test_increment():
          ????x?=?5
          ????expected?=?6
          ????actual?=?increment(x)
          ????assert?actual?==?expected


          def?test_decrement():
          ????x?=?5
          ????expected?=?4
          ????actual?=?decrement(x)
          ????assert?actual?==?expected

          注意:測試代碼是使用pytest框架編寫的。

          當(dāng)然,您可以編寫更多的測試腳本來測試具有不同值的兩個函數(shù),甚至可以對測試進(jìn)行參數(shù)化。但是,最后您將使用預(yù)定義的值來測試這兩個功能。

          使用基于屬性的測試庫(例如Hypothesis )編寫測試是不同的。在這里,您可以指定要測試的類型以及軟件的工作方式或行為方式。然后該庫根據(jù)指定的類型生成隨機(jī)值來進(jìn)行實際測試功能。

          讓我們看看如何使用Hypothesis來測試我們的兩個功能。

          #?test_increment_decrement_hypothesis.py

          from?hypothesis?import?given
          import?hypothesis.strategies?as?st

          from?increment_decrement?import?decrement
          from?increment_decrement?import?increment


          @given(st.integers())
          def?test_increment(x):
          ????expected?=?x?+?1
          ????actual?=?increment(x)
          ????assert?actual?==?expected


          @given(st.integers())
          def?test_decrement(x):
          ????expected?=?x?-?1
          ????actual?=?decrement(x)
          ????assert?actual?==?expected

          如您所見,這兩個測試腳本都有一個參數(shù)xx的值是由Hypothesis使用integers()方法生成的。Hypothesis提供了各種方法。本質(zhì)上,這些方法對應(yīng)于內(nèi)置類型或其他結(jié)構(gòu),并生成與給定類型匹配的隨機(jī)數(shù)據(jù)。

          聽起來不錯,不是嗎?但是,如果我們想測試具有特定值的函數(shù)以確保它也可以使用該值怎么辦?Hypothesis提供了一個@example()裝飾器,您可以在其中定義一個值,即使該值不屬于隨機(jī)生成的測試數(shù)據(jù)集,也可以將該值傳遞給相應(yīng)的函數(shù)。

          讓我們舉個簡單的例子:

          #?div.py

          def?div(dividend:?int,?divisor:?int)?->?int:
          ????return?dividend?//?divisor

          我們定義了一個函數(shù)div(),該函數(shù)接受一個除數(shù)和一個被除數(shù)并返回兩者的商。請注意,這兩個參數(shù)都是整型數(shù)據(jù),因此結(jié)果也應(yīng)該是整型數(shù)據(jù),我們使用Python的//運(yùn)算符執(zhí)行整數(shù)除法。

          為了測試div()函數(shù),我們創(chuàng)建了一個新的測試文件test_div.py并編寫了一個名為test_div()的測試腳本。

          #?test_div.py

          from?hypothesis?import?example
          from?hypothesis?import?given
          import?hypothesis.strategies?as?st

          from?div?import?div


          @given(dividend=st.integers(),?divisor=st.integers())
          def?test_div(dividend,?divisor):
          ????if?divisor?==?0:
          ????????expected?=?-1
          ????else:
          ????????expected?=?dividend?//?divisor
          ????actual?=?div(dividend,?divisor)
          ????assert?actual?==?expected

          同樣,我們使用Hypothesisintegers()方法生成除數(shù)和被除數(shù)的值。我們編寫的測試腳本可能通過也可能不會通過,具體取決于執(zhí)行時Hypothesis產(chǎn)生的值。為了確保始終將值0傳遞給div()函數(shù),我們將@example(1,0)添加到test_div()函數(shù)。因此,即使div()不在隨機(jī)生成的數(shù)據(jù)集中,也至少會用除數(shù)的值0調(diào)用一次。

          如果我們按原樣運(yùn)行測試腳本,則test_div()將始終失敗。因此,讓我們修改div()函數(shù)來處理這種情況并使測試通過:

          #?div.py

          def?div(dividend:?int,?divisor:?int)?->?int:
          ????if?divisor?==?0:
          ????????return?-1
          ????return?dividend?//?divisor

          概要

          本文主要講了什么是基于屬性的測試以及為什么有用。此外,您快速瀏覽了Hypothesis庫,該庫使您可以編寫基于屬性的測試并與pytest測試一起執(zhí)行。

          習(xí)Python

          關(guān)注戀習(xí)Python,Python都好練
          好文章,我在看??
          瀏覽 44
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  三级乱伦片 | 你懂的日韩欧美在线视频 | 一道本一区二区视频 | 久七精品在线 | 亚洲人操逼 |