SoFunction
Updated on 2025-03-02

pytest parameterization:@Detailed explanation

pytest parameterization:@

The built-in decorator can be used to parameterize the test functions.

Here is a typical example

Check if the expected output of a specific input matches:

  • test_expectation.py
import pytest
@("test_input, expected", [("3+5", 8), ("2+4", 6), ("6*9", 42),])
def test_eval(test_input, expected):
    assert eval(test_input) == expected

The decorator @parametrize defines three different sets of data (test_input, expected) and test_eval will use these three sets of data.

Perform three times:

$ pytest
=========================== test session starts ============================
platform linux ‐‐ Python , pytest‐, py‐, pluggy‐
cachedir: $PYTHON_PREFIX/.pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items
test_expectation.py ..F [100%]
================================= FAILURES =================================
____________________________ test_eval[6*9‐42] _____________________________
test_input = '6*9', expected = 42
@("test_input,expected", [
("3+5", 8),
("2+4", 6),
("6*9", 42),
])
def test_eval(test_input, expected):
> assert eval(test_input) == expected
E AssertionError: assert 54 == 42
E + where 54 = eval('6*9')
test_expectation.py:8: AssertionError
==================== 1 failed, 2 passed in 0.12 seconds ====================

In this example, only one set of data is failed

Normally you can see input and output as function parameters in traceback.

Notice:

You can also use parameterized markers for modules or classes to make multiple test functions run under different test sets.

You can also use mark for a parameter in the parameter set, such as the following is built-in:

  • test_exception.py
import pytest
@("test_input, expected", [("3+5", 8), ("2+4", 6), ("6*9", 42, marks=),])
def test_eval(test_input, expected):
    assert eval(test_input) == expected

The operation results are as follows:

$ pytest
=========================== test session starts ============================
platform linux ‐‐ Python , pytest‐, py‐, pluggy‐
cachedir: $PYTHON_PREFIX/.pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items
test_expectation.py ..x [100%]
=================== 2 passed, 1 xfailed in 0.12 seconds ====================

The use case that failed before has been marked as xfailed here.

If the parameterized list is an empty list, for example, the parameters are dynamically generated by a function, please refer to the empty_parameter_set_mark option.

You can use multiple parameterize decorators for a function, so that the parameters of multiple decorators will be called in combination:

import pytest
@("x", [0, 1])
@("y", [2, 3])
def test_foo(x, y):
    pass

This exhausts all combinations of x and y and calls.

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.