Pytest 根据 mark.parameterize 值选择测试?



我从这里看到,我可以根据它们的分数挑选测试,如下所示:

pytest -v -m webtest

假设我有一个这样装饰的测试:

@pytest.mark.parametrize('platform,configuration', (
pytest.param('win', 'release')
pytest.param('win', 'debug')))
def test_Foo(self):

我想做如下事情:

pytest -v -m parameterize.configuration.release

这样,我使用"release"参数而不是"debug"参数运行test_Foo。 有没有办法做到这一点? 我想我可以通过编写一个包装器测试然后只向下传递所需的参数来做到这一点,但我想避免这样做,因为我们已经有大量测试参数化,如描述的那样,我想避免编写大量的包装器测试。

您可以使用-k进行基于表达式的筛选:

$ pytest -k win-release

将仅运行名称中包含win-release的测试。您可以列出所有名称,而无需通过发出以下命令来执行测试

$ pytest --collect-only -q

如果表达式不够,您始终可以通过添加自定义筛选逻辑来扩展pytest,例如,通过命令行参数传递参数名称和值,并仅选择相应地参数化的测试:

# conftest.py
def pytest_addoption(parser):
parser.addoption('--param-name', action='store',  help='parameter name')
parser.addoption('--param-value', action='store',  help='parameter value')

def pytest_collection_modifyitems(session, config, items):
param_name = config.getoption('--param-name')
param_value = config.getoption('--param-value')
if param_name and param_value:
items[:] = [item for item in items
if hasattr(item, 'callspec')
and param_name in item.callspec.params
and item.callspec.params[param_name] == param_value]

现在您可以例如致电

$ pytest --param-name=platform --param-value=win

并且只会执行用platform=win参数化的测试。

通过锄头获得官方答案的另一种方法是使用 pytest-pilot 创建一个特殊的标记并应用它:

conftest.py:

from pytest_pilot import EasyMarker
mymark = EasyMarker('mymark', has_arg=False, mode='hard_filter')

test_so.py:

import pytest
from .conftest import mymark
@pytest.mark.parametrize('platform,configuration', (
mymark.param('win', 'release'),
pytest.param('win', 'debug')
))
def test_foo(platform, configuration):
pass

您现在可以运行pytest --mymark,它仅正确运行带有标记的测试

test_sotest_so.py::test_foo[win-release] PASSED                         [ 50%]
test_sotest_so.py::test_foo[win-debug] SKIPPED                          [100%]

当然,它可能并不适用于所有情况,因为它需要代码修改;但是对于高级过滤模式,或者如果过滤仍然存在并且您希望有一些CLI快捷方式来执行它,那么它可能很有趣。注意:我是这个库;)的作者

最新更新