Skip to content

Parametrized Testing

Parametrization lets you run the same test with multiple sets of inputs, avoiding repetition and making your tests easier to maintain.

NOTE

Even though parametrize is accessed via pytest.mark, it is not a marker. Instead, it is a helper function that generates multiple test cases and behaves more like a decorator factory than a simple marker label.

  • The following example generates three separate test cases, one for each input:
python
@pytest.mark.parametrize("value", [0, 1, 2])
def test_is_non_negative(value):
    assert value >= 0
  • You can also parametrize multiple arguments as shown below:
python
@pytest.mark.parametrize("x, y, result", [
    (1, 2, 3),
    (2, 3, 5),
    (10, -1, 9),
])
def test_add(x, y, result):
    assert x + y == result
  • You’ve already seen how to target individual tests. Similarly, you can also target a parametrized test case using its auto-generated identifier (or nodeid in pytest terminology):
shell
# This targets the first test case in the example code above
pytest test_math.py::test_add[1-2-3]
  • If you don't want to use these auto-generated IDs and wish to provide your own ID values, you can do so using the ids parameter:
python
@pytest.mark.parametrize(
    "x, y, result",
    [
        (1, 2, 3),
        (2, 3, 5),
        (10, -1, 9),
    ],
    ids=["test_one", "test_two", "test_three"]
)
def test_add(x, y, result):
    assert x + y == result

# Now you can target tests like this - `pytest test_math.py::test_add[test_one]`
  • Alternatively, you can do the same using pytest.param function:
python
@pytest.mark.parametrize(
    "x, y, result",
    [
        pytest.param(1, 2, 3, id="test_one"),
        pytest.param(2, 3, 5, id="test_two"),
        pytest.param(10, -1, 9, id="test_three"),
    ]
)
def test_add(x, y, result):
    assert x + y == result