Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprenda Test Parametrization in Pytest: Running Tests with Multiple Inputs | Mastering Pytest Framework
Python Advanced Concepts
course content

Conteúdo do Curso

Python Advanced Concepts

Python Advanced Concepts

1. Mastering Python Modules and Imports
2. Mastering Error Handling in Python
3. Mastering File Handling in Python
4. Mastering Pytest Framework
5. Mastering Unittest Framework
6. Mastering Iterators and Generators in Python

book
Test Parametrization in Pytest: Running Tests with Multiple Inputs

Parameterized testing is crucial for enhancing test coverage without writing numerous test functions for scenarios that only differ by their inputs and expected outputs. This approach not only saves time but also increases the clarity and maintainability of test suites by:

  • Reducing code duplication and the potential for errors in test code;
  • Enabling easy addition of new test cases by simply adding parameters;
  • Facilitating comprehensive testing across a wide range of inputs.

Let's consider a simple function that calculates the average of two numbers. There can be a logical error if to forget to put braces. We'll use @pytest.mark.parametrize to test this function with several pairs of numbers.

# Function to test
def calculate_average(num1, num2):
    return (num1 + num2) / 2

# Test function using pytest's parametrize
import pytest

@pytest.mark.parametrize(
    "num1, num2, expected",
    [
        (10, 20, 15),
        (20, 30, 25),
        (5, 5, 5)
    ])
def test_calculate_average(num1, num2, expected):
    assert (calculate_average(num1, num2) == expected), f"Average of {num1} and {num2} should be equal to {(num1 + num2) / 2}"

This example demonstrates how to run test_calculate_average with three different sets of numbers, checking if the function correctly computes their average.

Syntax with id

The id parameter is used to assign an identifier to each set of inputs, which helps to identify tests more easily in the test output:

 @pytest.mark.parametrize("num1, num2, expected", [
    pytest.param(10, 20, 15, id="integers"),
    pytest.param(20, 30, 25, id="more integers"),
    pytest.param(5, 5, 5, id="equal numbers")
])
def test_calculate_average_with_ids(num1, num2, expected):
    assert calculate_average(num1, num2) == expected

Using pytest.param allows for more granular control over each test case, including setting individual IDs directly.

Syntax with ids

You can also provide a unique ID for each test case using ids, which makes test reports more readable:

@pytest.mark.parametrize("num1, num2, expected", [
    (10, 20, 15),
    (20, 30, 25),
    (5, 5, 5)
], ids=["integers", "more integers", "equal numbers"])
def test_calculate_average_with_ids(num1, num2, expected):
    assert calculate_average(num1, num2) == expected

In this code, each set of parameters has an associated ID that describes the test case, which will appear in the test output.

Here's what the output might look like:

===================== test session starts ======================
collected 3 items

test_example.py::test_calculate_average_with_ids[integers] FAILED
test_example.py::test_calculate_average_with_ids[more integers] PASSED
test_example.py::test_calculate_average_with_ids[equal numbers] PASSED

=========================== FAILURES ===========================
________________ test_calculate_average_with_ids[integers] ________________

num1 = 10, num2 = 20, expected = 15

    def test_calculate_average_with_ids(num1, num2, expected):
>       assert calculate_average(num1, num2) == expected
E       assert 20 == 15 
E        +  where 20 = calculate_average(10, 20)

test_example.py:10: AssertionError
================== 1 failed, 2 passed in 0.23s ==================

1. Consider a function that multiplies two numbers. Complete the test case by filling in the missing parts:

2. What is the primary benefit of specifying identifiers using id or ids in @pytest.mark.parametrize?

question mark

Consider a function that multiplies two numbers. Complete the test case by filling in the missing parts:

Select the correct answer

question mark

What is the primary benefit of specifying identifiers using id or ids in @pytest.mark.parametrize?

Select the correct answer

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 4. Capítulo 4

Pergunte à IA

expand

Pergunte à IA

ChatGPT

Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo

course content

Conteúdo do Curso

Python Advanced Concepts

Python Advanced Concepts

1. Mastering Python Modules and Imports
2. Mastering Error Handling in Python
3. Mastering File Handling in Python
4. Mastering Pytest Framework
5. Mastering Unittest Framework
6. Mastering Iterators and Generators in Python

book
Test Parametrization in Pytest: Running Tests with Multiple Inputs

Parameterized testing is crucial for enhancing test coverage without writing numerous test functions for scenarios that only differ by their inputs and expected outputs. This approach not only saves time but also increases the clarity and maintainability of test suites by:

  • Reducing code duplication and the potential for errors in test code;
  • Enabling easy addition of new test cases by simply adding parameters;
  • Facilitating comprehensive testing across a wide range of inputs.

Let's consider a simple function that calculates the average of two numbers. There can be a logical error if to forget to put braces. We'll use @pytest.mark.parametrize to test this function with several pairs of numbers.

# Function to test
def calculate_average(num1, num2):
    return (num1 + num2) / 2

# Test function using pytest's parametrize
import pytest

@pytest.mark.parametrize(
    "num1, num2, expected",
    [
        (10, 20, 15),
        (20, 30, 25),
        (5, 5, 5)
    ])
def test_calculate_average(num1, num2, expected):
    assert (calculate_average(num1, num2) == expected), f"Average of {num1} and {num2} should be equal to {(num1 + num2) / 2}"

This example demonstrates how to run test_calculate_average with three different sets of numbers, checking if the function correctly computes their average.

Syntax with id

The id parameter is used to assign an identifier to each set of inputs, which helps to identify tests more easily in the test output:

 @pytest.mark.parametrize("num1, num2, expected", [
    pytest.param(10, 20, 15, id="integers"),
    pytest.param(20, 30, 25, id="more integers"),
    pytest.param(5, 5, 5, id="equal numbers")
])
def test_calculate_average_with_ids(num1, num2, expected):
    assert calculate_average(num1, num2) == expected

Using pytest.param allows for more granular control over each test case, including setting individual IDs directly.

Syntax with ids

You can also provide a unique ID for each test case using ids, which makes test reports more readable:

@pytest.mark.parametrize("num1, num2, expected", [
    (10, 20, 15),
    (20, 30, 25),
    (5, 5, 5)
], ids=["integers", "more integers", "equal numbers"])
def test_calculate_average_with_ids(num1, num2, expected):
    assert calculate_average(num1, num2) == expected

In this code, each set of parameters has an associated ID that describes the test case, which will appear in the test output.

Here's what the output might look like:

===================== test session starts ======================
collected 3 items

test_example.py::test_calculate_average_with_ids[integers] FAILED
test_example.py::test_calculate_average_with_ids[more integers] PASSED
test_example.py::test_calculate_average_with_ids[equal numbers] PASSED

=========================== FAILURES ===========================
________________ test_calculate_average_with_ids[integers] ________________

num1 = 10, num2 = 20, expected = 15

    def test_calculate_average_with_ids(num1, num2, expected):
>       assert calculate_average(num1, num2) == expected
E       assert 20 == 15 
E        +  where 20 = calculate_average(10, 20)

test_example.py:10: AssertionError
================== 1 failed, 2 passed in 0.23s ==================

1. Consider a function that multiplies two numbers. Complete the test case by filling in the missing parts:

2. What is the primary benefit of specifying identifiers using id or ids in @pytest.mark.parametrize?

question mark

Consider a function that multiplies two numbers. Complete the test case by filling in the missing parts:

Select the correct answer

question mark

What is the primary benefit of specifying identifiers using id or ids in @pytest.mark.parametrize?

Select the correct answer

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 4. Capítulo 4
some-alt