← Назад к вопросам
Как использовать unit тест с параметрами в pytest?
1.7 Middle🔥 211 комментариев
#Тестирование
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Параметризованные тесты в pytest
Параметризация позволяет запустить один тест с разными наборами данных, избежав дублирования кода. Это мощный инструмент для тестирования граничных случаев.
Базовая параметризация: @pytest.mark.parametrize
import pytest
@pytest.mark.parametrize("input,expected", [
(2, 4),
(3, 9),
(4, 16),
(-1, 1),
(0, 0),
])
def test_square(input, expected):
assert input ** 2 == expected
Это эквивалентно написанию 5 отдельных тестов.
Параметризация нескольких аргументов
@pytest.mark.parametrize("username,password,is_valid", [
("admin", "secret123", True),
("admin", "wrong", False),
("guest", "guest", True),
])
def test_login(username, password, is_valid):
result = authenticate(username, password)
assert result.is_valid == is_valid
Использование ids для читаемых названий
@pytest.mark.parametrize(
"user_id,expected_role",
[(1, "admin"), (2, "user"), (3, "moderator")],
ids=["admin_user", "regular_user", "moderator_user"]
)
def test_user_roles(user_id, expected_role):
user = get_user(user_id)
assert user.role == expected_role
ids делают названия тестов более информативными.
Вложенная параметризация
@pytest.mark.parametrize("x", [1, 2, 3])
@pytest.mark.parametrize("y", ["a", "b"])
def test_multiple_params(x, y):
# Выполнится 3 * 2 = 6 раз
assert x > 0
assert y in ["a", "b"]
Декартово произведение параметров.
Тестирование валидации
def validate_email(email: str) -> bool:
return "@" in email and "." in email
@pytest.mark.parametrize(
"email,valid",
[
("user@example.com", True),
("invalid.email", False),
("@example.com", False),
],
ids=["valid", "no_at", "no_local"]
)
def test_email_validation(email, valid):
assert validate_email(email) == valid
Параметризация с fixtures (indirect)
@pytest.fixture
def user(request):
user_data = request.param
return create_user(**user_data)
@pytest.mark.parametrize(
"user",
[
{"name": "Alice", "role": "admin"},
{"name": "Bob", "role": "user"},
],
indirect=True
)
def test_user_permissions(user):
if user.role == "admin":
assert user.can_delete_users
Hypothesis для property-based тестирования
from hypothesis import given, strategies as st
@given(st.integers(min_value=0, max_value=100))
def test_factorial_properties(n):
result = factorial(n)
assert result >= 1
Тестирование обработки ошибок
@pytest.mark.parametrize(
"invalid_input,expected_error",
[(None, ValueError), ("", ValueError), (-1, ValueError)]
)
def test_parse_invalid_input(invalid_input, expected_error):
with pytest.raises(expected_error):
parse_number(invalid_input)
Best practices
1. Используйте ids для читаемости — делает тесты понятнее в отчётах.
2. Группируйте связанные тесты — отделяйте valid и invalid случаи.
3. Избегайте слишком много параметров — если больше 3-4, используйте объекты.
4. Информативные сообщения об ошибках — помогают быстро найти проблему.
Параметризация в pytest — это стандартный способ тестирования граничных случаев без дублирования кода.