TGViewer
Zen of Python Zen of Python @zen_of_python · 18.8K subscribers
Post #4434 2.23K
@pytest.mark.parametrize: Как параметризировать тесты

Тестирование кода может быть утомительным процессом. Когда у вас есть множество похожих тестовых случаев, написание отдельных функций для каждого часто приводит к дублированию кода. Именно здесь на помощь приходит функция @pytest.mark.parametrize.

Начнем с простого примера. У нас есть функция add_nums(), которая складывает числа из списка:


def add_nums(numbers):
return sum(numbers)


Без parametrize тесты могли бы выглядеть так:


def test_123():
assert add_nums([1, 2, 3]) == 6

def test_negatives():
assert add_nums([1, 2, -3]) == 0

def test_empty():
assert add_nums([]) == 0


Что не так с этим подходом? Дублирование кода: каждая тестовая функция повторяет одну и ту же структуру. Вместо написания трех отдельных функций, мы можем создать одну параметризованную функцию:


import pytest

@pytest.mark.parametrize(
"nums, expected_total",
[
([1, 2, 3], 6),
([1, 2, -3], 0),
([], 0),
]
)
def test_add_nums(nums, expected_total):
assert add_nums(nums) == expected_total


1. @pytest.mark.parametrize — это специальный декоратор pytest
2. Параметры "nums, expected_total" — имена параметров функции
3. Тестовые данные — список кортежей, где каждый содержит значения для одного теста

Pytest автоматически вызывает вашу функцию с каждым набором параметров:


# Первый вызов
test_add_nums([1, 2, 3], 6)

# Второй вызов
test_add_nums([1, 2, -3], 0)

# Третий вызов
test_add_nums([], 0)


Результат: 3 отдельных теста, каждый из которых может пройти или упасть.


Кастомные ID для тестов

По умолчанию pytest генерирует автоматические ID для тестов, но они могут быть не очень понятными. Вы можете задать свои:


@pytest.mark.parametrize(
"nums, expected_total",
[
([1, 2, 3], 6),
([1, 2, -3], 0),
([], 0),
],
ids=["positive_numbers", "mixed_numbers", "empty_list"]
)
def test_add_nums(nums, expected_total):
assert add_nums(nums) == expected_total


Теперь при запуске тестов вы увидите:

test_add_nums[positive_numbers] PASSED
test_add_nums[mixed_numbers] PASSED
test_add_nums[empty_list] PASSED



Вложенная параметризация

Можно комбинировать несколько параметризаций:


@pytest.mark.parametrize("x", [1, 2, 3])
@pytest.mark.parametrize("y", [10, 20])
def test_multiply(x, y):
assert x * y == x * y


Это создаст 6 тестов: (1,10), (1,20), (2,10), (2,20), (3,10), (3,20).

#основы
@zen_of_python
  • 👍 13
  • 🔥 2
  • ❤ 1
More from @zen_of_python
  1. Sep 26, 2026Как собирать динамические фильтры Django через Q-объекты Q() представляет условие для SQL-…
  2. Sep 26, 2026Почему str.splitlines() видит больше переносов, чем чтение файла У Python два разных понят…
  3. Sep 26, 2026Как вручную разрешить ленивый импорт в Python У объекта, созданного через lazy import json…
  4. Sep 25, 2026Почему Python предупреждает о последовательности \477 и как это исправить В строках Python…
  5. Sep 25, 2026Как запускать Python-код в песочнице на MicroPython и WebAssembly В проектах Саймона Уилли…
  6. Sep 25, 2026Как emojet ускоряет работу с эмодзи в Python Библиотека emojet преобразует названия в эмод…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →