如何处理测试失败

在第一次(或 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

这将会在每次失败(或 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_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 命令),输出捕获将恢复。

使用内置 breakpoint 函数

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 检测到这些情况并发出警告,该警告在测试运行摘要中可见。

除非在命令行中给出 -p no:unraisableexception(对于不可引发的异常)和 -p no:threadexception(对于线程异常)选项,否则插件会自动为 pytest 运行启用。

可以使用 pytest.mark.filterwarnings 标记选择性地静默警告。 警告类别为 pytest.PytestUnraisableExceptionWarningpytest.PytestUnhandledThreadExceptionWarning