Pytest官方教程-22-API參考-Fuctions

目錄:

  1. 安裝及入門
  2. 使用和調用方法
  3. 原有TestSuite使用方法
  4. 斷言的編寫和報告
  5. Pytest fixtures:清晰 模塊化 易擴展
  6. 使用Marks標記測試用例
  7. Monkeypatching/對模塊和環境進行Mock
  8. 使用tmp目錄和文件
  9. 捕獲stdout及stderr輸出
  10. 捕獲警告信息
  11. 模塊及測試文件中集成doctest測試
  12. skip及xfail: 處理不能成功的測試用例
  13. Fixture方法及測試用例的參數化
  14. 緩存: 使用跨執行狀態
  15. unittest.TestCase支持
  16. 運行Nose用例
  17. 經典xUnit風格的setup/teardown
  18. 安裝和使用插件
  19. 插件編寫
  20. 編寫鉤子(hook)方法
  21. 運行日志
  22. API參考
    1. 方法(Functions)
    2. 標記(Marks)
    3. 鉤子(Hooks)
    4. 裝置(Fixtures)
    5. 對象(Objects)
    6. 特殊變量(Special Variables)
    7. 環境變量(Environment Variables)
    8. 配置選項(Configuration Options)
  23. 優質集成實踐
  24. 片狀測試
  25. Pytest導入機制及sys.path/PYTHONPATH
  26. 配置選項
  27. 示例及自定義技巧
  28. Bash自動補全設置

API參考-Fuctions

22-API參考-01-Functions

參考
該頁面包含對pytest API的完整參考。

方法(Functions)

pytest.approx

斷言兩個數字(或兩組數字)在某個容差范圍內彼此相等。

由于浮點運算復雜性,我們直覺期望相等的數字并不總是如此:

 0.1 + 0.2 == 0.3
False

編寫測試時通常會遇到此問題,例如,確保浮點值是您期望的值。處理此問題的一種方法是斷言兩個浮點數等于某個適當的容差范圍內:

 abs((0.1 + 0.2) - 0.3) < 1e-6
True

但是,這樣的比較寫作起來既乏味又難以理解。此外,通常不鼓勵像上面這樣的絕對比較,因為沒有適合所有情況的容忍度。 1e-6對周圍的數字有好處1,但對于非常大的數字而言太小而對于非常小的數字而言太大。最好將公差表示為預期值的一小部分,但這樣的相對比較更難以正確和簡潔地書寫。

approx班采用語法是盡可能直觀執行浮點比較:

 from pytest import approx
>>> 0.1 + 0.2 == approx(0.3)
True

相同的語法也適用于數字序列:

 (0.1 + 0.2, 0.2 + 0.4) == approx((0.3, 0.6))
True

字典

 {'a': 0.1 + 0.2, 'b': 0.2 + 0.4} == approx({'a': 0.3, 'b': 0.6})
True

numpy 數組:

 import numpy as np                                                          
>>> np.array([0.1, 0.2]) + np.array([0.2, 0.4]) == approx(np.array([0.3, 0.6])) 
True

對于numpy標量的數組:

 import numpy as np                                         
>>> np.array([0.1, 0.2]) + np.array([0.2, 0.1]) == approx(0.3) 
True

默認情況下,approx1e-6其預期值的相對容差 (即百萬分之一)內的數字視為相等。如果預期值是這樣的0.0,那么這種處理會產生令人驚訝的結果 ,因為除了0.0本身之外什么都不是0.0。為了不那么令人驚訝地處理這種情況,approx還要考慮在1e-12其預期值的絕對容差內的數字是相等的。Infinity和NaN是特殊情況。無論相對容差如何,無窮大只被視為與自身相等。默認情況下,NaN不被視為等于任何內容,但您可以通過將nan_ok參數設置為True 來使其等于自身。(這是為了便于比較使用NaN的數組表示“無數據”。)

通過將參數傳遞給approx構造函數,可以更改相對容差和絕對容差:

 1.0001 == approx(1)
False
>>> 1.0001 == approx(1, rel=1e-3)
True
>>> 1.0001 == approx(1, abs=1e-3)
True

如果您指定abs但不指定rel,則比較將不會考慮相對容差。換句話說,1e-6如果超過指定的絕對容差,則默認相對容差范圍內的兩個數字仍將被視為不相等。如果同時指定兩個 absrel,如果滿足任一公差,則數字將被視為相等:

 1 + 1e-8 == approx(1)
True
>>> 1 + 1e-8 == approx(1, abs=1e-12)
False
>>> 1 + 1e-8 == approx(1, rel=1e-6, abs=1e-12)
True

如果您正在考慮使用approx,那么您可能想知道它與比較浮點數的其他好方法的比較。所有這些算法都基于相對和絕對容差,并且應該在大多數情況下達成一致,但它們確實存在有意義的差異:

  • math.isclose(a, b, rel_tol=1e-9, abs_tol=0.0):True如果相對誤差滿足WRT無論是ab,或者如果絕對容差得到滿足。因為相對容差是a和兩者一起計算的b,所以該測試是對稱的(即既不是a也不 b是“參考值”)。如果要進行比較,則必須指定絕對容差,0.0因為默認情況下沒有容差。僅在python> = 3.5中可用。 更多信息…
  • numpy.isclose(a, b, rtol=1e-5, atol=1e-8):如果和之間的差值小于相對容差wrt 和絕對容差之a和,b則為真b。由于相對容差僅計算為wrt b,因此該測試是不對稱的,您可以將其b視為參考值。支持比較序列由numpy.allclose。提供。 更多信息…
  • unittest.TestCase.assertAlmostEqual(a, b):如果a并且b 在絕對容差范圍內,則為真1e-7。不考慮相對容差,并且不能改變絕對容差,因此該功能不適用于非常大或非常小的數字。此外,它只在子類中可用,unittest.TestCase并且它很難看,因為它不遵循PEP8。 更多信息…
  • a == pytest.approx(b, rel=1e-6, abs=1e-12):如果滿足相對容差b或者滿足絕對容差,則為真。由于相對容差僅計算為wrt b,因此該測試是不對稱的,您可以將其b視為參考值。在明確指定絕對公差而非相對公差的特殊情況下,僅考慮絕對公差。

警告

在3.2版中更改。

為了避免不一致的行為,TypeError是提高了>>=<<=比較。以下示例說明了問題:

 0.1 + 1e-10  # calls approx(0.1).__gt__(0.1 + 1e-10)
assert 0.1 + 1e-10 > approx(0.1)  # calls approx(0.1).__lt__(0.1 + 1e-10)

在第二個例子中,人們期望 被調用。但相反,用于比較。這是因為豐富比較的調用層次結構遵循固定行為。更多信息…approx(0.1).__le__(0.1 + 1e-10)``approx(0.1).__lt__(0.1 +1e-10)

pytest.fail

教程Skip和xfail:處理無法成功的測試
使用給定消息顯式失敗執行測試。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 參數: |

  • msgstr) - 顯示用戶失敗原因的消息。
  • pytracebool) - 如果為false,則msg表示完整的失敗信息,并且不報告任何python回溯。

pytest.skip

使用給定消息跳過執行測試。

應僅在測試(設置,調用或拆除)期間或使用allow_module_level標志在收集期間調用此函數。此函數也可以在doctests中調用。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 參數: | allow_module_levelbool) - 允許在模塊級別調用此函數,跳過模塊的其余部分。默認為False。 |

注意:
最好在可能的情況下使用pytest.mark.skipif標記來聲明在某些條件下跳過的測試,例如不匹配的平臺或依賴項。同樣,使用指令(請參閱doctest.SKIP)靜態跳過doctest。# doctest:+SKIP

pytest.importorskip

導入并返回請求的模塊modname,或者如果無法導入模塊,則跳過當前測試。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 參數: |

  • modnamestr) - 要導入的模塊的名稱
  • minversionstr) - 如果給定,導入的模塊__version__屬性必須至少為此最小版本,否則仍會跳過測試。
  • reasonstr) - 如果給定,則無法導入模塊時,此原因顯示為消息。

pytest.xfail

由于給定的原因,強制執行測試或設置功能。

只應在測試(設置,調用或拆卸)期間調用此函數。

注意

最好在可能的情況下使用pytest.mark.xfail標記,在某些條件(如已知錯誤或缺少的功能)下聲明測試是否為xfailed。

pytest.exit

退出測試過程。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 參數: |

  • msgstr) - 退出時顯示的消息。
  • returncodeint) - 返回退出pytest時使用的代碼。

pytest.main

執行進程內測試運行后返回退出代碼。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 參數: |

  • args - 命令行參數列表。
  • plugins - 初始化期間要自動注冊的插件對象列表。

pytest.param

pytest.mark.parametrize調用或 參數化夾具中指定參數。

@pytest.mark.parametrize("test_input,expected", [
    ("3+5", 8),
    pytest.param("6*9", 42, marks=pytest.mark.xfail),
])
def test_eval(test_input, expected):
    assert eval(test_input) == expected

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 參數: |

  • values - 按順序的參數集值的變量args。
  • 標記 - 要應用于此參數集的單個標記或標記列表。
  • idstr) - 屬于此參數集的id。

pytest.raises

教程關于預期異常的斷言

斷言代碼塊/函數調用會引發expected_exception 或引發失敗異常。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 參數: |

  • match - 如果指定,則斷言異常與text或regex匹配
  • 消息 - (自4.1棄用)如果指定,提供了一種定制的失敗消息,如果異常沒有升高

|

使用pytest.raises的上下文管理器,這將捕獲特定類型的異常:

 with raises(ZeroDivisionError):
...    1/0

如果代碼塊沒有引發預期的異常(ZeroDivisionError在上面的示例中),或者根本沒有異常,則檢查將失敗。

您還可以使用keyword參數match來斷言異常與text或regex匹配:

 with raises(ValueError, match='must be 0 or None'):
...     raise ValueError("value must be 0 or None")

>>> with raises(ValueError, match=r'must be \d+/pre>):
...     raise ValueError("value must be 42")

上下文管理器生成一個ExceptionInfo對象,可用于檢查捕獲的異常的詳細信息:

 with raises(ValueError) as exc_info:
...     raise ValueError("value must be 42")
>>> assert exc_info.type is ValueError
>>> assert exc_info.value.args[0] == "value must be 42"

自4.1版本后不推薦使用:在上下文管理器表單中,您可以使用keyword參數 message指定在pytest.raises檢查失敗時將顯示的自定義失敗消息。這已被棄用,因為它被認為是容易出錯的,因為用戶通常意味著使用它match

注意

pytest.raises用作上下文管理器時,值得注意的是,應用正常的上下文管理器規則,并且引發的異常必須是上下文管理器范圍內的最后一行。之后,在上下文管理器范圍內的代碼行將不會被執行。例如:

 value = 15
>>> with raises(ValueError) as exc_info:
...     if value > 10:
...         raise ValueError("value must be <= 10")
...     assert exc_info.type is ValueError  # this will not execute

相反,必須采取以下方法(注意范圍的差異):

 with raises(ValueError) as exc_info:
...     if value > 10:
...         raise ValueError("value must be <= 10")
...
>>> assert exc_info.type is ValueError

使用 pytest.mark.parametrize

使用pytest.mark.parametrize時 ,可以對測試進行參數化,使得某些運行引發異常,而其他運行則不會。

有關示例,請參閱參數化條件提升

遺產形式

可以通過傳遞一個名為lambda來指定一個可調用的:

 raises(ZeroDivisionError, lambda: 1/0)
<ExceptionInfo ...>

或者你可以用參數指定一個任意的callable:

 def f(x): return 1/x
...
>>> raises(ZeroDivisionError, f, 0)
<ExceptionInfo ...>
>>> raises(ZeroDivisionError, f, x=0)
<ExceptionInfo ...>

上面的表單完全受支持,但不建議使用新代碼,因為上下文管理器表單被認為更具可讀性且不易出錯。

注意:
與Python中捕獲的異常對象類似,顯式清除對返回ExceptionInfo對象的本地引用可以幫助Python解釋器加速其垃圾回收。

清除這些引用會中斷引用循環(ExceptionInfo- >捕獲異常 - >幀堆棧引發異常 - >當前幀堆棧 - >局部變量 - > ExceptionInfo),這會使Python保留從該循環引用的所有對象(包括當前幀中的所有局部變量) )活著,直到下一個循環垃圾收集運行。有關try更多詳細信息,請參閱官方Python 語句文檔。

pytest.deprecated_call

教程確保代碼觸發棄用警告

上下文管理器,可用于確保代碼塊觸發a DeprecationWarningPendingDeprecationWarning

 import warnings
>>> def api_call_v2():
...     warnings.warn('use v3 of this api', DeprecationWarning)
...     return 200

>>> with deprecated_call():
...    assert api_call_v2() == 200

deprecated_call也可以通過傳遞函數來使用,*args并且*kwargs在這種情況下,它將確保調用產生上面的警告類型之一。func(*args, **kwargs)

pytest.register_assert_rewrite

教程斷言重寫

注冊一個或多個要在導入時重寫的模塊名稱。

此函數將確保此模塊或程序包內的所有模塊將重寫其assert語句。因此,您應確保在實際導入模塊之前調用此方法,如果您是使用包的插件,則通常在init.py中調用。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 舉: | TypeError - 如果給定的模塊名稱不是字符串。 |

pytest.warns

教程使用警告功能發出警告

斷言代碼會引發一類特定的警告。

具體來說,參數expected_warning可以是警告類或警告類序列,并且with塊內部必須發出該類或類的警告。

該助手生成一個warnings.WarningMessage對象列表,每個警告引發一個對象。

此函數可用作上下文管理器,pytest.raises也可以使用任何其他方法 :

 with warns(RuntimeWarning):
...    warnings.warn("my warning", RuntimeWarning)

在上下文管理器表單中,您可以使用keyword參數match來斷言異常與text或regex匹配:

 with warns(UserWarning, match='must be 0 or None'):
...     warnings.warn("value must be 0 or None", UserWarning)

>>> with warns(UserWarning, match=r'must be \d+/pre>):
...     warnings.warn("value must be 42", UserWarning)

>>> with warns(UserWarning, match=r'must be \d+/pre>):
...     warnings.warn("this is not here", UserWarning)
Traceback (most recent call last):
  ...
Failed: DID NOT WARN. No warnings of type ...UserWarning... was emitted...

pytest.freeze_includes

教程凍結pytest

返回pytest使用的模塊名稱列表,應由cx_freeze包含。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,182評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,489評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,290評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,776評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,510評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,866評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,860評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,036評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,585評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,331評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,536評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,058評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,754評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,154評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,469評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,273評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,505評論 2 379

推薦閱讀更多精彩內容