如何处理测试失败¶
在第一次(或 N 次)失败后停止¶
在第一次 (N) 失败后停止测试过程
pytest -x # stop after first failure
pytest --maxfail=2 # stop after two failures
在 pytest 中使用 pdb — Python 调试器¶
在失败时进入 pdb¶
Python 自带一个名为 pdb 的内置 Python 调试器。pytest 允许通过命令行选项进入 pdb 提示符
pytest --pdb
这将对每次失败(或 KeyboardInterrupt)调用 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命令),输出捕获将恢复。
使用内置的 breakpoint 函数¶
Python 3.7 引入了内置的 breakpoint() 函数。Pytest 支持使用 breakpoint(),具有以下行为
当调用
breakpoint()且PYTHONBREAKPOINT设置为默认值时,pytest 将使用自定义的内部 PDB 跟踪 UI,而不是系统默认的Pdb。测试完成后,系统将默认恢复到系统
Pdb跟踪 UI。当向 pytest 传入
--pdb时,自定义的内部 Pdb 跟踪 UI 将用于breakpoint()和失败的测试/未处理的异常。
--pdbcls可用于指定自定义调试器类。
故障处理程序¶
版本 5.0 中新增。
标准模块 faulthandler 可用于在段错误或超时后转储 Python 追溯。
除非在命令行上给出 -p no:faulthandler,否则该模块会自动为 pytest 运行启用。
此外,配置选项 faulthandler_timeout=X 可用于在测试完成时间超过 X 秒时转储所有线程的追溯。
注意
此功能已从外部 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。