我有一个pytest测试,它针对两个不同的数据库测试多个输入。我使用参数化标记两次:
@pytest.mark.parametrize(
"input_type",
[
pytest.param("input_1"),
pytest.param("input_2"),
],
)
@pytest.mark.parametrize(
"db_type",
[
pytest.param("db_type_1"),
pytest.param("db_type_2"),
],
)
我的经验是,只有当使用db_type_2
运行input_1
时(例如(,测试才会因错误而失败但是用不同的db传递运行相同的输入。我只想将input_1
和db_type_2
组合标记为xfail,而不应将所有其他组合标记为xfail。我找不到怎么做。
如果将db_type_2
标记为xfail:
@pytest.mark.parametrize(
"db_type",
[
pytest.param("db_type_1"),
pytest.param("db_type_2", marks=pytest.mark.xfail)
],
)
所有的输入都会失败,这不是我想要的行为。有人能帮我吗?
您不能根据pytest.mark.parametrize
/pytest.param
中的完整参数集来标记测试,有关其他参数的信息根本不存在。通常,我在一个单独的夹具中移出测试参数的后处理,然后可以根据完整的测试参数集来更改测试。示例:
@pytest.mark.parametrize('x', range(10))
@pytest.mark.parametrize('y', range(20))
def test_spam(x, y):
assert False
我们总共进行了200次测试;假设我们要对x=3
、y=15
和x=8
、y=1
进行xfail
测试。我们添加了一个新的fixturexfail_selected_spams
,它可以在test_spam
启动之前访问x
和y
,并在必要时将xfail
标记附加到测试实例:
@pytest.fixture
def xfail_selected_spams(request):
x = request.getfixturevalue('x')
y = request.getfixturevalue('y')
allowed_failures = [
(3, 15), (8, 1),
]
if (x, y) in allowed_failures:
request.node.add_marker(pytest.mark.xfail(reason='TODO'))
要注册夹具,请使用pytest.mark.usefixtures
:
@pytest.mark.parametrize('x', range(10))
@pytest.mark.parametrize('y', range(20))
@pytest.mark.usefixtures('xfail_selected_spams')
def test_spam(x, y):
assert False
现在运行测试时,我们将得到198 failed, 2 xfailed
结果,因为所选的两个测试预计会失败。
您可以创建一个函数,该函数将在测试采集时执行,并根据数据处理参数化和xfail
标记
def data_source():
input_types = ['input_1', 'input_2']
db_types = ['db_type_1', 'db_type_2']
for tup in itertools.product(input_types, db_types):
marks = []
if tup == ('input_1', 'db_type_2'):
marks.append(pytest.mark.xfail(reason=f'{tup}'))
yield pytest.param(tup, marks=marks)
@pytest.mark.parametrize('test_data', data_source())
def test_example(self, test_data):
assert test_data != ('input_1', 'db_type_2')
CCD_ 21允许添加另一个输入列表,而不修改代码的任何其他部分,除了允许输入的CCD_。