Parametrizing Tests
Learn about pytest parametrization and the different types of parametrization techniques with interactive code examples.
We'll cover the following...
- Introduction to parametrization
- Basic test parametrization
- Parametrized fixtures
- Parametrization of external data sources
- Indirect parametrization
- Parametrizing conditional raising
- Parametrizing with pytest.param
- Parametrizing with pytest_generate_tests
- Parametrizing Python classes
- Conclusion
- Test your learning!
Introduction to parametrization
Test parametrization is a feature in pytest that allows us to write a single test function and test it with multiple input values. It is a way of writing concise tests that can cover many cases with minimal code. This feature is especially useful when we want to test a function with varying input parameters.
The main benefit of this is concise code. Instead of writing many separate test functions with the same code, we can write a single test function with parameters, which makes the test code more concise and easier to manage. Testing code with a variety of inputs can increase the coverage of the tests and help us find bugs more easily. This also makes test code easier to maintain in the future.
In the following sections, we will explore how to use test parametrization in pytest.
Basic test parametrization
To use test parametrization in pytest, we can use the @pytest.mark.parametrize
decorator. This decorator takes the name of the parameterized argument(s) as a string or list, followed by the list of values to use for each parameter.
import pytestfrom main import multiply@pytest.mark.parametrize("x, y, result", [(2, 3, 6),(1, 1, 1),(0, 5, 0),(-2, 3, -6),])def test_multiply(x, y, result):assert multiply(x, y) == result
In the above code, @pytest.mark.parametrize
is used to define the input values for the test_multiply
function. The function is tested with four different input values, each consisting of two integers and an expected result. The test passes if multiply(x, y)
returns the expected result. We can also use a tuple or a dictionary to specify the parameter and its values.
When parametrizing tests in pytest, it’s important to understand how pytest generates test names based on the parameters. By default, pytest generates test names that include the parameter values, making it easy to identify which tests passed or failed. However, we can customize the test name format using the ids
parameter of the @pytest.mark.parametrize
decorator, which allows us to specify a custom test name for each test case.
import pytest@pytest.mark.parametrize("x, y", [(1, 2), (3, 4)], ids=["test_case1", "test_case2"])def test_addition(x, y):assert x + y == x + y
By default, pytest generates the test names as test_addition[1-2]
and test_addition[3-4]
.
In the above case, pytest generates the following test names: test_addition[test_case1]
and test_addition[test_case2]
.
One more example of basic parametrization is the following:
import pytest@pytest.mark.parametrize("x", [0, 1])@pytest.mark.parametrize("y", [2, 3])def test_foo(x, y):print("x:", x, "y:", y)assert x + y > 0
This will run the test with the arguments set to