Parametrizing Tests in pytest
Parametrizing in pytest enables you to test a function with multiple sets of input data. This approach reduces code duplication and ensures thorough testing across various scenarios.
Parametrizing Test Functions with @pytest.mark.parametrize
The @pytest.mark.parametrize
decorator allows you to run a single test function multiple times with different input values.
Syntax
@pytest.mark.parametrize("parameter_name", [value1, value2, ...])
You can also test with multiple parameters:
@pytest.mark.parametrize("param1, param2", [(value1, value2), (value3, value4)])
Example: Single Parameter
import pytest
@pytest.mark.parametrize("number", [1, 2, 3, 4, 5])
def test_is_even(number):
assert number % 2 == 0, f"{number} is not even"
This test runs five times, once for each number in the list.
Example: Multiple Parameters
@pytest.mark.parametrize("base, exponent, expected", [
(2, 3, 8),
(3, 2, 9),
(5, 0, 1),
(1, 10, 1),
])
def test_power(base, exponent, expected):
assert base ** exponent == expected
Here, test_power
runs four times, using each tuple of values.
Parametrizing Fixtures for Dynamic Test Scenarios
You can also parametrize fixtures to dynamically provide data to your tests. This is useful for testing with varying setups.
Defining a Parametrized Fixture
Use the params
argument in @pytest.fixture
to define multiple inputs for a fixture.
Example:
@pytest.fixture(params=["apple", "banana", "cherry"])
def fruit(request):
return request.param
def test_fruit_length(fruit):
assert len(fruit) > 0
- The
request
object provides access to the current parameter value. - This test runs three times, once for each fruit.
Combining Fixture Parametrization with @pytest.mark.parametrize
You can use both techniques together for powerful test scenarios.
Example:
@pytest.fixture(params=[2, 3, 5])
def multiplier(request):
return request.param
@pytest.mark.parametrize("number, expected", [(10, 20), (15, 30), (7, 14)])
def test_multiplication(number, expected, multiplier):
assert number * multiplier == expected * multiplier
This test combines parametrized inputs from the fixture and the decorator.
Benefits of Parametrization
- Efficiency: Write one test function to cover multiple scenarios.
- Clarity: Reduce repetitive code and improve readability.
- Scalability: Test functions adapt easily to changing requirements by modifying input sets.
Summary
- Use
@pytest.mark.parametrize
to test functions with multiple input sets. - Parametrize fixtures with the
params
argument for dynamic setups. - Combine both methods for complex test cases requiring diverse data inputs.
Parametrization is a cornerstone of robust testing in pytest, ensuring your code handles a wide variety of scenarios without repetitive or redundant test definitions.