How to Parametrize Tests in Python with pytest

This code demonstrates how to use pytest's @pytest.mark.parametrize decorator to run a single test function against multiple input sets, ensuring comprehensive coverage with minimal code duplication.

Easy Python 3.9+ Aug 9, 2026 Modern tooling 15 views 0 copies

Requires third-party packages — install first
pip install pytest

Python code

31 lines
Python 3.9+
import pytest


def multiply(a, b):
    return a * b


@pytest.mark.parametrize("x, y, expected", [
    (2, 3, 6),
    (4, 5, 20),
    (0, 10, 0),
    (7, 1, 7),
])
def test_multiply(x, y, expected):
    result = multiply(x, y)
    assert result == expected, f"multiply({x}, {y}) = {result}, expected {expected}"


if __name__ == "__main__":
    # Demonstrate manually without pytest
    cases = [
        (2, 3, 6),
        (4, 5, 20),
        (0, 10, 0),
        (7, 1, 7),
    ]
    for x, y, expected in cases:
        result = multiply(x, y)
        status = "PASS" if result == expected else "FAIL"
        print(f"{status}: multiply({x}, {y}) = {result} (expected {expected})")
    print("All parametrized test cases completed.")

Output

stdout
PASS: multiply(2, 3) = 6 (expected 6)
PASS: multiply(4, 5) = 20 (expected 20)
PASS: multiply(0, 10) = 0 (expected 0)
PASS: multiply(7, 1) = 7 (expected 7)
All parametrized test cases completed.

How it works

The @pytest.mark.parametrize decorator in this code defines a list of argument tuples, and pytest automatically runs the test function once for each tuple, unpacking the values into the x, y, and expected parameters. This approach reduces redundancy by avoiding separate test functions for each case. pytest collects and reports each combination as an individual test, making failures easy to isolate. The assert statement with a custom message provides clear diagnostics when a case fails. The __main__ block serves as a manual demonstration, illustrating the same test logic without the pytest runner.

Common mistakes

  • Forgetting to install pytest before running the test suite
  • Not including an `expected` value in every parametrized tuple
  • Using a list of lists instead of tuples, which can cause unpacking confusion
  • Misplacing the decorator above the function definition

Variations

  1. Use `pytest.mark.parametrize` with separate lists for each argument and `zip` them together
  2. Define parametrize arguments as a list of dictionaries with `pytest.param` for more control
  3. Use a fixture that yields parametrized data for more complex test setups

Real-world use cases

  • Database queries: run the same SQL logic test against multiple input data sets.
  • API validation: test endpoint responses for various request payloads and expected status codes.
  • String processing: verify a function handles different formats, edge cases, and special characters.

Sponsored

Run locally

This sample needs third-party packages, so it cannot run in the browser IDE. Copy the code above, install the packages shown at the top, then run it in your own Python environment.

More from Modern tooling

Related tutorials and quizzes for this topic.