Exploring Test Case Strategies: Individual Functions and Pytest Parameterize

To test the same function with multiple test cases, you can do either of the following:

Separate test functions:

This approach involves creating individual test functions for each test case.

def test_add_positive():
    assert add(2, 3) == 5

def test_add_negative():
    assert add(-2, -3) == -5

def test_add_mixed():
    assert add(-2, 3) == 1

def test_add_zero():
    assert add(0, 5) == 4

Output:

pytest_parametrize_example.py ...F                                       [100%]

=================================== FAILURES ===================================
________________________________ test_add_zero _________________________________

    def test_add_zero():
>       assert add(0, 5) == 4
E       assert 5 == 4
E        +  where 5 = add(0, 5)

pytest_parametrize_example.py:14: AssertionError
=========================== short test summary info ============================
FAILED pytest_parametrize_example.py::test_add_zero - assert 5 == 4
========================= 1 failed, 3 passed in 0.05s ==========================

Pros:

  • Each test case is clearly isolated and easy to understand at a glance.

Cons:

  • Code duplication – the test structure is repeated for each case.
  • Adding new test cases requires writing a new function each time.
  • Changes to test structure only need to be made in multiple places.

Use pytest parameterize

This approach uses pytest’s parametrize decorator to run the same test function with different inputs.

import pytest


def add(num1, num2):
    return num1 + num2


@pytest.mark.parametrize(
    "a, b, expected",
    [(2, 3, 5), (-2, -3, -5), (-2, 3, 1), (0, 5, 4)],
    ids=["positive numbers", "negative numbers", "mixed signs", "zero and positive"],
)
def test_add(a, b, expected):
    assert add(a, b) == expected

Output:

pytest_parametrize_example.py ...F                                       [100%]

=================================== FAILURES ===================================
_________________________ test_add[zero and positive] __________________________

a = 0, b = 5, expected = 4

    @pytest.mark.parametrize(
        "a, b, expected",
        [(2, 3, 5), (-2, -3, -5), (-2, 3, 1), (0, 5, 4)],
        ids=["positive numbers", "negative numbers", "mixed signs", "zero and positive"],
    )
    def test_add(a, b, expected):
>       assert add(a, b) == expected
E       assert 5 == 4
E        +  where 5 = add(0, 5)

pytest_parametrize_example.py:14: AssertionError
=========================== short test summary info ============================
FAILED pytest_parametrize_example.py::test_add[zero and positive] - assert 5 == 4
========================= 1 failed, 3 passed in 0.06s ==========================

Pros:

  • Easy to add new test cases by adding to the parameter list.
  • Changes to test structure only need to be made in one place.

Cons:

  • The purpose of each test case might be less immediately clear, especially for complex tests.

Choosing between these methods depends on your project’s needs. Use individual functions when clarity is crucial. Use parametrize when dealing with numerous similar cases.

Scroll to Top