如何處理測試失敗

在第一次(或第 N 次)失敗後停止

要在第一次(第 N 次)失敗後停止測試程序

pytest -x           # stop after first failure
pytest --maxfail=2  # stop after two failures

pdb — Python 除錯器 與 pytest 搭配使用

在失敗時轉到 pdb

Python 附帶一個內建的 Python 除錯器,稱為 pdbpytest 允許透過命令列選項轉到 pdb 提示

pytest --pdb

這會在每次失敗(或鍵盤中斷)時呼叫 Python 除錯器。通常你可能只想針對第一次失敗的測試執行此操作,以了解特定失敗情況

pytest -x --pdb   # drop to PDB on first failure, then end test session
pytest --pdb --maxfail=3  # drop to PDB for first three failures

請注意,在任何失敗時,例外資訊都會儲存在 sys.last_valuesys.last_typesys.last_traceback 中。在互動式使用中,這允許使用任何除錯工具轉到驗屍除錯。你也可以手動存取例外資訊,例如

>>> import sys
>>> sys.last_traceback.tb_lineno
42
>>> sys.last_value
AssertionError('assert result == "ok"',)

在測試開始時轉到 pdb

pytest 允許透過命令列選項在每個測試開始時立即轉到 pdb 提示

pytest --trace

這會在每個測試開始時呼叫 Python 除錯器。

設定中斷點

要在程式碼中設定中斷點,請在程式碼中使用原生 Python import pdb;pdb.set_trace() 呼叫,而 pytest 會自動停用該測試的輸出擷取

  • 其他測試中的輸出擷取不受影響。

  • 任何先前已擷取的測試輸出都將照樣處理。

  • 結束偵錯器工作階段(透過 continue 指令)時,輸出擷取會繼續進行。

使用內建中斷點函式

Python 3.7 引入了內建 breakpoint() 函式。Pytest 支援使用 breakpoint(),並具有以下行為

  • 當呼叫 breakpoint(),且 PYTHONBREAKPOINT 設為預設值時,pytest 會使用自訂內部 PDB 追蹤 UI,而不是系統預設的 Pdb

  • 當測試完成時,系統會預設回到系統 Pdb 追蹤 UI。

  • 如果將 --pdb 傳遞給 pytest,則自訂內部 Pdb 追蹤 UI 會與 breakpoint() 和失敗的測試/未處理的例外一起使用。

  • --pdbcls 可用於指定自訂偵錯器類別。

錯誤處理常式

在版本 5.0 中新增。

可以使用 faulthandler 標準模組在段落錯誤或逾時後傾印 Python 追蹤回溯。

除非在命令列中指定 -p no:faulthandler,否則會自動為 pytest 執行啟用該模組。

此外,faulthandler_timeout=X 設定選項可用於傾印所有執行緒的追蹤回溯,如果測試花費超過 X 秒才能完成(Windows 上不適用)。

注意事項

此功能已從外部 pytest-faulthandler 外掛整合,有兩個小差異

  • 要停用它,請使用 -p no:faulthandler,而不是 --no-faulthandler:前者可用於任何外掛,因此它可以節省一個選項。

  • --faulthandler-timeout 命令列選項已變成 faulthandler_timeout 組態選項。它仍然可以使用 -o faulthandler_timeout=X 從命令列進行組態。

關於無法引發例外和未處理執行緒例外的警告

已在版本 6.2 中新增。

未處理例外是在無法傳播到呼叫者的情況下引發的例外。最常見的情況是在 __del__ 實作中引發的例外。

未處理執行緒例外是在 Thread 中引發但未處理的例外,導致執行緒不正常終止。

這兩種類型的例外通常被視為錯誤,但可能會被忽略,因為它們不會導致程式本身崩潰。Pytest 會偵測這些情況,並在測試執行摘要中發出可見的警告。

這些外掛會自動啟用於 pytest 執行,除非在命令列中提供了 -p no:unraisableexception(對於無法引發的例外)和 -p no:threadexception(對於執行緒例外)選項。

警告可以使用 pytest.mark.filterwarnings 標記選擇性地靜音。警告類別為 pytest.PytestUnraisableExceptionWarningpytest.PytestUnhandledThreadExceptionWarning