你在正确的轨道上。部分问题在于您已使用套件 A 和套件 B 标记了测试函数,因此该函数被视为两者的一部分。
您使用的参数标记样式可能在 14 年有效(并且在 pytest 3 后期仍然有效),但在最新的 pytest 版本 (5.x) 中无效。
这些示例使用最新的样式,至少可以追溯到 pytest 3.x。
来自the pytest docs:
使用参数化时,应用标记将使其应用于每个单独的测试。但是,也可以将标记应用于单个测试实例:
import pytest
@pytest.mark.foo
@pytest.mark.parametrize(
("n", "expected"), [(1, 2), pytest.param(1, 3, marks=pytest.mark.bar), (2, 3)]
)
def test_increment(n, expected):
assert n + 1 == expected
在上面的示例中,使用标记 foo 将运行该测试将所有参数(包括 bar)。使用标记 bar 将仅使用 1 个标记的参数运行该测试。
因此,对于您的示例,您可以这样做(请原谅,我将除标记外的所有名称都更新为 PEP8 标准):
@pytest.mark.parametrize("input_parameter", [
# use this input for Suite A and Suite B
pytest.param(10, marks=[pytest.mark.suiteA, pytest.mark.suiteB]),
# use this input only for Suite B
pytest.param(12, marks=pytest.mark.suiteB),
# this input will run when no markers are specified
(13),
])
def test_print_input_parameter(input_parameter):
print(input_parameter)
你必须去掉函数上面的两个标记装饰器。你只需要这个参数装饰器。
根据 cmets,输入 10 被标记以确保它只能与套件 A 或套件 B 一起运行。如果调用其中一个或两个,它将执行。
输入 12 绑定到单个标记,suiteB。只有在调用 suiteB 时才会执行。
我还添加了输入值 13 作为默认未标记测试运行的示例。正常情况下,这不会对 suiteA 或 suiteB(或 suiteC 或任何其他标记过滤器)执行,但如果没有指定标记(其余标记也会)运行。
或者,您可以这样做:
@pytest.mark.suiteB # this function is a part of suiteB
@pytest.mark.parametrize("input_parameter", [
# use this input for Suite A and Suite B
pytest.param(10, marks=pytest.mark.suiteA),
# use this input only for Suite B
(12),
# this input is also part of Suite B thanks to the function decorator, as well as suiteC and suiteD
pytest.param(13, marks=[pytest.mark.suiteC, pytest.mark.suiteD]),
])
def test_print_input_parameter(input_parameter):
print(input_parameter)
使用您原来的两个参数,您确实有一个完整的套件 B 测试,其中一个参数仅适用于套件 A。
在这种情况下,函数装饰器在 suiteB 下运行整个测试。如果指定了suiteA,只会执行10个。
因为用到了函数装饰器,所以我编的参数13,和这个函数的所有参数一样,也是suiteB的一部分。我可以将它添加到任意数量的其他标记中,但函数装饰器确保此测试将使用 suiteB 下的所有参数运行。
根据您的示例,此替代方案将起作用,但如果您有任何不重叠的参数(例如,13 是 not 在 suiteB 下运行),您必须单独指定它们中的每一个,例如中间的例子。