pytest8.x版本 中文使用文档-------2.pytest如何调用

目录

指定要运行哪些测试

在模块中运行测试

在目录中运行测试

按关键字表达式运行测试

按集合参数运行测试

按标记表达式运行测试

从包运行测试

从文件中读取参数

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

分析测试执行时间

管理插件的加载

提前加载插件

禁用插件

调用pytest的其他方法

通过python - m pytest调用pytest

从Python代码调用pytest



通常,pytest是用命令pytest调用的(关于调用 pytest 的其他方式,请参见下文)。这将执行当前目录及其子目录中所有文件名以test_*.py或\*_test.py形式结尾的文件中的所有测试。更一般地说,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]

表示要运行 tests/test_mod.py 文件中名为 test_func 的测试函数,并且这个函数是通过参数化(可能使用了 @pytest.mark.parametrize 装饰器)定义的,这里 [x1,y2] 指定了参数化测试的一个具体参数组合。

按标记表达式运行测试

pytest -m slow

将运行所有使用 @pytest.mark.slow 装饰器装饰的测试。有关更多信息,请参阅标记(Marks)。

从包运行测试

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 --collect-only -q 命令用于收集测试,但不实际运行它们。-q 选项表示“quiet”模式,即减少输出信息。这个命令会列出所有可收集的测试项(即 pytest 能够找到的测试),但不会执行它们。你可以将这个命令的输出重定向到一个文件中,然后编辑该文件来指定你想要运行的测试。这对于快速生成一个包含所有可用测试的列表,并从中选择你想要运行的特定测试非常有用。

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

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

分析测试执行时间

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

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

默认情况下,除非在命令行中传递了 -vv(表示更详细的输出),否则 pytest 不会显示耗时过短(<0.005秒)的测试项持续时间。

管理插件的加载

提前加载插件

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

pytest -p mypluginmodule

该选项接收一个名称参数,它可以是:

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

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

pytest -p pytest_cov

pytest_cov 是一个插件,它用于在 pytest 测试期间收集代码覆盖率信息。当你运行 pytest -p pytest_cov 时,pytest 会在测试开始之前加载 pytest_cov 插件,这样它就可以在测试执行过程中收集代码覆盖率数据。测试完成后,pytest_cov 插件通常会报告覆盖率统计信息,包括哪些代码被执行了,哪些没有。

禁用插件

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

示例:要禁用加载负责从文本文件执行 doctest 测试的插件 doctest,可以像这样调用 pytest

pytest -p no:doctest

调用pytest的其他方法

通过python - m pytest调用pytest

你可以在命令行中通过Python解释器调用测试:

Python -m pytest[…]

这几乎等同于直接调用命令行脚本 pytest [...],但通过 Python 调用还会将当前目录添加到 sys.path 中。

sys.path 是一个列表,包含了 Python 解释器在查找模块时会搜索的路径。当你通过 python -m pytest 这种方式来运行 pytest 时,Python 解释器会首先执行 pytest 模块,并且因为它是以模块的方式被调用的,所以 Python 会自动将当前目录(即你运行命令时所在的目录)添加到 sys.path 中。这样做的好处是,如果你的测试脚本或模块位于当前目录下,或者依赖于当前目录下的其他模块,那么它们就可以被正确地导入和执行了。

从Python代码调用pytest

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

retcode = pytest.main()

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

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

在这个例子中,pytest.main()函数被调用,并传递了一个包含选项和参数的列表。这里,"-x"选项表示在第一个测试失败时立即停止测试,"mytestdir"是包含测试文件的目录名。pytest.main()函数执行测试,并返回一个整数退出代码,其中0表示成功,非0值表示有测试失败或发生了其他错误。

你还可以向 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 已被添加,并且它的钩子函数被调用了:

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

定义了一个名为 MyPlugin 的类,它有一个方法 pytest_sessionfinish,这是一个 pytest 钩子函数,它会在测试会话结束时被调用。然后,在脚本的 if __name__ == "__main__": 块中,我们调用了 pytest.main() 函数,并将一个包含 -qq 选项的列表和包含 MyPlugin 实例的列表作为参数传递给它。-qq 选项用于减少 pytest 的输出,只显示必要的测试摘要信息。

通过向 pytest.main() 传递 plugins 参数,我们可以将自定义的插件或钩子添加到 pytest 测试会话中。在这个例子中,当测试会话结束时,pytest_sessionfinish 钩子函数会被调用,打印出 "*** test run reporting finishing" 消息。

请注意

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

为了避免这个问题,你可以考虑以下几种方法:

  1. 在单独的进程中运行测试:每次需要运行测试时,都启动一个新的 Python 进程。这可以通过在命令行中直接调用 pytest 命令或使用 Python 的 subprocess 模块来实现。

  2. 清理 Python 的模块缓存:在调用 pytest.main() 之前,你可以尝试清除 Python 的模块缓存,但这通常不是推荐的做法,因为它可能会导致不可预测的行为和性能问题。

  3. 使用 pytest 的内置功能:如果你正在编写一个需要多次运行测试的脚本,考虑是否可以使用 pytest 的其他功能(如测试套件、测试集合或参数化测试)来满足你的需求,而不是多次调用 pytest.main()

  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值