Pytest在多重参数化时忽略某些参数

-1 投票
1 回答
36 浏览
提问于 2025-04-14 15:34

我在想有没有办法跳过下面例子中的参数对:

@pytest.mark.parametrize("foo", [1, 2, 3])
@pytest.mark.parametrize("bar", [4, 5, 6])

像这样运行的话,总共会有9次运行(1,4;1,5;1,6;2,4;2,5;2,6;3,4;3,5;3,6)。我想要实现的是,让foo中的1和2与bar中的每个参数一起运行,但在运行foo中的3时忽略bar中的4,这样就会跳过参数对3,4,理想情况下,这对参数在测试输出中根本不出现。

在pytest中有没有办法做到这一点?我知道我可以使用类似下面的方式:

if foo == 3 and bar == 4:
    pytest.skip("Something")

但我在想有没有更简洁的方法,因为如果我想忽略多个参数对,这样会变得很麻烦。

1 个回答

2

你可以这样做:

import pytest
from itertools import product


@pytest.mark.parametrize(
    "foo, bar",
    [x for x in product([1, 2, 3], [4, 5, 6]) if x not in {(3, 4)}]
)
def test_something_2(foo, bar):
    assert True

在输出中,你根本看不到对 (3,4) 的测试:

============================= test session starts ==============================
platform linux -- Python 3.11.8, pytest-8.1.1, pluggy-1.4.0 -- /home/larsks/tmp/python/.venv/bin/python
cachedir: .pytest_cache
rootdir: /home/larsks/tmp/python
collecting ... collected 8 items

test_foo.py::test_something_2[1-4] PASSED                                [ 12%]
test_foo.py::test_something_2[1-5] PASSED                                [ 25%]
test_foo.py::test_something_2[1-6] PASSED                                [ 37%]
test_foo.py::test_something_2[2-4] PASSED                                [ 50%]
test_foo.py::test_something_2[2-5] PASSED                                [ 62%]
test_foo.py::test_something_2[2-6] PASSED                                [ 75%]
test_foo.py::test_something_2[3-5] PASSED                                [ 87%]
test_foo.py::test_something_2[3-6] PASSED                                [100%]

============================== 8 passed in 0.01s ===============================

当然,你可以把跳过的配对放到一个变量里,这样如果配对数量超过一个的话,代码会看起来更整洁:

import pytest
from itertools import product

ignored_pairs = {(3, 4)}


@pytest.mark.parametrize(
    "foo, bar",
    [x for x in product([1, 2, 3], [4, 5, 6]) if x not in ignored_pairs]
)
def test_something_2(foo, bar):
    assert True

撰写回答