如何處理測試失敗¶
在第一次(或第 N 次)失敗後停止¶
要在第一次(第 N 次)失敗後停止測試程序
pytest -x # stop after first failure
pytest --maxfail=2 # stop after two failures
將 pdb — Python 除錯器 與 pytest 搭配使用¶
在失敗時轉到 pdb¶
Python 附帶一個內建的 Python 除錯器,稱為 pdb。pytest
允許透過命令列選項轉到 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_value
、sys.last_type
和 sys.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.PytestUnraisableExceptionWarning
和 pytest.PytestUnhandledThreadExceptionWarning
。