如何调用 pytest

通常,pytest 通过命令 pytest 调用(有关其他调用 pytest 的方式,请参见下文)。这将执行当前目录及其子目录中所有名称符合 test_*.py*_test.py 形式的文件中的所有测试。更一般地,pytest 遵循标准测试发现规则

指定要运行的测试

Pytest 支持多种方式从命令行或文件中运行和选择测试(有关从文件读取参数,请参见下文)。

运行模块中的测试

pytest test_mod.py

运行目录中的测试

pytest testing/

按关键字表达式运行测试

pytest -k 'MyClass and not method'

这将运行包含与给定字符串表达式匹配的名称(不区分大小写)的测试,该表达式可以包含使用文件名、类名和函数名作为变量的 Python 运算符。上面的示例将运行 TestMyClass.test_something 但不运行 TestMyClass.test_method_simple。在 Windows 上运行时,在表达式中使用 "" 而不是 ''

按集合参数运行测试

传入相对于工作目录的模块文件名,然后是使用 :: 字符分隔的类名和函数名等说明符,以及用 [] 括起来的参数化参数。

要在模块中运行特定的测试

pytest tests/test_mod.py::test_func

运行类中的所有测试

pytest tests/test_mod.py::TestClass

指定特定的测试方法

pytest tests/test_mod.py::TestClass::test_method

指定测试的特定参数化

pytest tests/test_mod.py::test_func[x1,y2]

按标记表达式运行测试

运行所有用 @pytest.mark.slow 装饰器标记的测试

pytest -m slow

运行所有用带注解的 @pytest.mark.slow(phase=1) 装饰器标记的测试,其中 phase 关键字参数设置为 1

pytest -m "slow(phase=1)"

更多信息请参见标记

从包中运行测试

pytest --pyargs pkg.testing

这将导入 pkg.testing 并使用其文件系统位置来查找和运行测试。

从文件读取参数

8.2 版本新增。

上述所有内容都可以通过使用 @ 前缀从文件中读取

pytest @tests_to_run.txt

其中 tests_to_run.txt 每行包含一个条目,例如:

tests/test_file.py
tests/test_mod.py::test_func[x1,y2]
tests/test_mod.py::TestClass
-m slow

此文件也可以使用 pytest --collect-only -q 生成并根据需要进行修改。

获取版本、选项名称、环境变量的帮助

pytest --version   # shows where pytest was imported from
pytest --fixtures  # show available builtin function arguments
pytest -h | --help # show help on command line and config file options

分析测试执行持续时间

6.0 版本中已更改。

获取超过 1.0 秒的最慢 10 个测试持续时间列表

pytest --durations=10 --durations-min=1.0

默认情况下,pytest 不会显示过短(小于 0.005 秒)的测试持续时间,除非在命令行中传入 -vv

管理插件加载

早期加载插件

您可以使用 -p 选项在命令行中显式地早期加载插件(内部和外部)

pytest -p mypluginmodule

该选项接受一个 name 参数,它可以是:

  • 一个完整的模块点分名称,例如 myproject.plugins。这个点分名称必须是可导入的。

  • 插件的入口点名称。这是插件注册时传递给 importlib 的名称。例如,要早期加载 pytest-cov 插件,您可以使用

    pytest -p pytest_cov
    

禁用插件

要在调用时禁用加载特定插件,请将 -p 选项与前缀 no: 一起使用。

例如:要禁用加载 doctest 插件(负责从文本文件执行 doctest 测试),请像这样调用 pytest

pytest -p no:doctest

其他调用 pytest 的方式

通过 python -m pytest 调用 pytest

您可以从命令行通过 Python 解释器调用测试

python -m pytest [...]

这几乎等同于直接调用命令行脚本 pytest [...],不同之处在于通过 python 调用还会将当前目录添加到 sys.path

从 Python 代码中调用 pytest

您可以直接从 Python 代码中调用 pytest

retcode = pytest.main()

这就像您从命令行调用“pytest”一样。它不会引发 SystemExit,而是返回退出代码。如果您不向其传递任何参数,main 会从进程的命令行参数(sys.argv)中读取参数,这可能不是您想要的。您可以显式地传入选项和参数

retcode = pytest.main(["-x", "mytestdir"])

您可以向 pytest.main 指定额外的插件

# content of myinvoke.py
import sys

import pytest


class MyPlugin:
    def pytest_sessionfinish(self):
        print("*** test run reporting finishing")


if __name__ == "__main__":
    sys.exit(pytest.main(["-qq"], plugins=[MyPlugin()]))

运行它将显示 MyPlugin 已添加且其 hook 已被调用

$ python myinvoke.py
*** test run reporting finishing

注意

调用 pytest.main() 将导致导入您的测试以及它们导入的任何模块。由于 Python 导入系统的缓存机制,在同一进程中对 pytest.main() 进行后续调用将不会反映两次调用之间对这些文件的更改。因此,不建议在同一进程中多次调用 pytest.main()(例如,为了重新运行测试)。