2

我有一个 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"),
    ],
)

我的经验是仅在input_1使用db_type_2(例如)测试由于错误而失败但使用不同的数据库通过运行相同的输入时。我只想将input_1anddb_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)
    ],
)

所有输入都将失败,这不是我正在寻找的行为。有人可以帮我吗?

4

2 回答 2

1

您不能根据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 个测试;假设我们要xfail测试x=3,y=15x=8, y=1。我们添加一个新的固定装置,它可以在启动之前和之前xfail_selected_spams访问,并在必要时将标记附加到测试实例:xytest_spamxfail

@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结果,因为两个选定的测试预计会失败。

于 2022-01-08T12:14:09.453 回答
1

您可以创建一个函数,该函数将在测试收集时间执行并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')

itertools.productif允许添加另一个输入列表,而无需修改代码的任何其他部分,允许输入的条件除外。

于 2022-01-09T06:00:13.350 回答