有没有办法指定从文件运行哪些 pytest 测试?

Posted

技术标签:

【中文标题】有没有办法指定从文件运行哪些 pytest 测试?【英文标题】:Is there a way to specify which pytest tests to run from a file? 【发布时间】:2016-07-27 04:45:00 【问题描述】:

有没有办法选择pytest 测试从文件中运行? 例如,包含要执行的测试列表的文件foo.txt

tests_directory/foo.py::test_001
tests_directory/bar.py::test_some_other_test

或者,有没有办法使用 pytest 从不同的目录中选择多个测试,在测试名称中没有共同的模式?

pytest -k <pattern> 允许单个模式。

一种选择是针对每个测试使用pytest.mark,但我的要求是运行来自不同文件的不同测试组合。

有没有办法为每个模式指定多个模式和测试文件名?

或者

有没有办法在文件中指定确切的测试路径并将该文件作为输入提供给pytest

或者

是否有可以用于此目的的钩子函数?

【问题讨论】:

【参考方案1】:

您可以使用-k option 运行具有不同模式的测试用例:

py.test tests_directory/foo.py tests_directory/bar.py -k 'test_001 or test_some_other_test'

这将运行名称为 test_001test_some_other_test 的测试用例,取消选择其余测试用例。

注意:这将选择以 test_001 或 test_some_other_test 开头的任何测试用例。例如,如果您有测试用例 test_0012,它也会被选中。

【讨论】:

谢谢。但是如果 foo.py 和 bar.py 中有一个同名的测试(比如 test_001),它最终会从两者中执行。 是的,任何与模式匹配的东西都会被执行,正如我在注释中提到的那样 但这对我来说是个问题。我想从哪个文件中选择要执行的测试。 @NamGVU ` -k ` 应该是py.test path/to/test/file.py -k function_name_test【参考方案2】:

指定测试/选择测试

Pytest 支持从命令行运行和选择测试的多种方式。

在模块中运行测试

pytest test_mod.py

在目录中运行测试

pytest testing/

通过关键字表达式运行测试

pytest -k "MyClass and not method"

这将运行包含与给定字符串表达式匹配的名称的测试,其中可以包括使用文件名、类名和函数名作为变量的 Python 运算符。上面的示例将运行 TestMyClass.test_something 而不是 TestMyClass.test_method_simple

按节点 ID 运行测试

每个收集到的测试都分配有一个唯一的nodeid,它由模块文件名和类名、函数名和参数化参数等说明符组成,由:: 字符分隔。

在模块中运行特定测试:

pytest test_mod.py::test_func

在命令行中指定测试方法的另一个例子:

pytest test_mod.py::TestClass::test_method

通过标记表达式运行测试

pytest -m slow

将运行所有使用 @pytest.mark.slow 装饰器装饰的测试。

欲了解更多信息,请参阅marks。

从包运行测试

pytest --pyargs pkg.testing

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

来源:https://docs.pytest.org/en/latest/usage.html#specifying-tests-selecting-tests

【讨论】:

test_mod.py::TestClass::test_method 最适合我【参考方案3】:

我的回答提供了一种在不同场景下运行测试子集的方法。

运行项目中的所有测试

pytest

在单个目录中运行测试

要从一个目录运行所有测试,请使用该目录作为参数 pytest:

pytest tests/my-directory

在单个测试文件/模块中运行测试

要运行一个充满测试的文件,请将文件的相对路径作为pytest 的参数列出:

pytest tests/my-directory/test_demo.py

运行单个测试函数

要运行单个测试函数,请添加 :: 和测试函数名称:

pytest -v tests/my-directory/test_demo.py::test_specific_function

使用-v,以便您查看运行了哪个函数。

运行单个测试类

要只运行一个类,就像我们对函数所做的那样,添加::,然后将类名添加到文件参数中:

pytest -v tests/my-directory/test_demo.py::TestClassName

运行测试类的单个测试方法

如果您不想运行所有测试类,只需一种方法,只需添加 另一个:: 和方法名:

pytest -v tests/my-directory/test_demo.py::TestClassName::test_specific_method

根据测试名称运行一组测试

-k 选项使您可以传入表达式以运行具有 表达式指定的某些名称作为测试名称的子字符串。 可以使用 andornot 来创建复杂的表达式。

例如,要运行名称中包含 _raises 的所有函数:

pytest -v -k _raises

【讨论】:

有趣的是,其中一些似乎扩展到参数化测试,例如如果您的测试以名称 test_demo.py::test_function[test_parameters_1] 运行,那么您可以在命令行上给出它来运行这个参数实例。【参考方案4】:

方法一:随机选择测试。又长又丑。

python -m pytest test/stress/test_performance.py::TestPerformance::test_continuous_trigger test/integration/test_config.py::TestConfig::test_valid_config

方法 2:使用关键字表达式。

注意:我正在按测试用例名称进行搜索。同样适用于 TestClass 名称。

案例 1:以下将运行找到的任何一个。因为我们使用了'OR'。

python -m pytest -k 'test_password_valid or test_no_configuration'

假设上面两个实际上是正确的,将运行 2 个测试。

案例 2: 现在一个不正确的名字和另一个正确的名字。

python -m pytest -k 'test_password_validzzzzzz or test_no_configuration' 

只找到并运行一个。

案例 3:如果您想运行所有提到的测试或无,请使用 AND

python -m pytest -k 'test_password_valid and test_no_configuration'

如果正确或不正确,两者都会运行。

案例4:只在一个文件夹中运行测试:

python -m pytest test/project1/integration -k 'test_password_valid or test_no_configuration'

案例 5:仅从一个文件运行测试。

python -m pytest test/integration/test_authentication.py -k 'test_password_expiry or test_incorrect_password'

案例 6: 运行除匹配项之外的所有测试。

python -m pytest test/integration/test_authentication.py -k 'not  test_incorrect_password'

【讨论】:

【参考方案5】:

如果您在两个不同的类中具有相同的方法名,而您只想运行其中一个,则可以这样做:

pytest tests.py -k 'TestClassName and test_method_name'

【讨论】:

【参考方案6】:

也许使用 pytest_collect_file() 钩子,您可以解析 .txt o .yaml 文件的内容,在其中指定测试,然后将它们返回到 pytest 核心。

pytest documentation 中显示了一个很好的示例。我想你在找什么。

【讨论】:

【参考方案7】:

根据有关按节点 ID 运行测试的文档

既然你在 foo.txt 中有所有节点 ID,只需运行

pytest `cat foo.txt | tr '\n' ' '`

这与以下命令相同(问题中有文件内容)

pytest tests_directory/foo.py::test_001 tests_directory/bar.py::test_some_other_test

【讨论】:

这太棒了。但就我而言,我有一个要跳过的测试节点 id 列表,每个节点 id 写在一个文本文件中,我如何告诉 pytest 运行 test.py 但跳过我文件中的那些?【参考方案8】:

这是一个可能的部分答案,因为它只允许选择测试脚本,而不是这些脚本中的单个测试。

而且它还受到我使用旧版兼容模式与 unittest 脚本的限制,因此不保证它可以与本机 pytest 一起使用。

这里是:

    创建一个新字典,比如subset_tests_directoryln -s tests_directory/foo.py

    ln -s tests_directory/bar.py

    注意隐含假定文件位于test_directory 中的导入。我必须通过在subset_tests_directory 中运行python foo.py 并根据需要进行更正来修复其中的几个问题。

    一旦测试脚本正确执行,cd subset_tests_directorypytest 就在那里。 Pytest 只会拾取它看到的脚本。

另一种可能性是在您当前的测试目录中进行符号链接,例如ln -s foo.py subset_foo.py 然后pytest subset*.py。这将避免需要调整您的导入,但它会使事情变得混乱,直到您删除符号链接。也为我工作。

【讨论】:

【参考方案9】:

假设测试名称是唯一的,您必须删除测试文件的名称:

cat foo.txt | cut -d : -f 3 > FAILED_TESTS.txt

正如其他人指出的那样使用-k,但您必须将文件的内容(即测试名称列表)作为单个字符串传递:

pytest -k "`cat FAILED_TESTS.txt | awk '$1=$1' RS= OFS=' or ' `"

awk 将用分隔符 or 替换新行,以便以 pytest 期望的格式连接测试名称。

【讨论】:

以上是关于有没有办法指定从文件运行哪些 pytest 测试?的主要内容,如果未能解决你的问题,请参考以下文章

pytest为什么不能运行指定目录下的用例

如何在使用 argparse 的文件上使用指定的测试目录运行 pytest?

pytest 运行命令

禁用 PyTest 递归检查?

如何在 pytest 中保持单元测试和集成测试分开

pytest之执行测试pytest.main()的使用