如何调用 pytest

How to invoke pytest

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

指定要运行的测试

Specifying which tests to run

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 并使用其文件系统位置查找并运行测试。

从文件读取参数

Added in version 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 生成,并根据需要进行修改。

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

Getting help on version, option names, environment variables

pytest --version # 显示 pytest 的导入位置
pytest --fixtures # 显示可用的内置函数参数
pytest -h | --help # 显示命令行和配置文件选项的帮助

分析测试执行持续时间

Profiling test execution duration

Changed in version 6.0.

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

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

默认情况下,除非在命令行上传递 -vv,否则 pytest 不会显示太短的测试持续时间(<0.005 秒)。

管理插件的加载

Managing loading of plugins

提前加载插件

Early loading plugins

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

pytest -p mypluginmodule

该选项接收 name 参数,可以是:

  • 完整模块的点名,例如 myproject.plugins。此点名必须是可导入的。

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

    pytest -p pytest_cov
    

禁用插件

Disabling plugins

要在调用时禁用加载特定插件,请使用 -p 选项以及前缀 no:

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

pytest -p no:doctest

调用 pytest 的其他方式

Other ways of calling pytest

通过 python -m pytest 调用 pytest

Calling pytest through python -m pytest

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

python -m pytest [...]

这几乎相当于直接调用命令行脚本 pytest [...] ,只是通过 python 调用也会将当前目录添加到 sys.path

从 Python 代码调用 pytest

Calling pytest from Python code

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

retcode = pytest.main()

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

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

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

# myinvoke.py 的内容
import sys

import pytest


class MyPlugin:
    def pytest_sessionfinish(self):
        print("*** 测试运行报告结束")


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

运行它将显示 MyPlugin 被添加并且其 钩子被调用:

$ python myinvoke.py
*** 测试运行报告结束

Note

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