Как параметризировать тесты в pytest
pytestданныекомандная строкапараметризациятестирование
Что проверяют
Умеете ли вы покрывать набор случаев одним тестом и знаете ли, как сохранить читаемость отчёта.
Как отвечать
Основной инструмент это декоратор параметризации:
@pytest.mark.parametrize(
("salary", "expected"),
[
(0, "не указана"),
(150_000, "150 000 ₽"),
(None, "не указана"),
],
ids=["ноль", "обычная", "пусто"],
)
def test_format_salary(salary, expected):
assert format_salary(salary) == expectedЧто стоит добавить:
- каждый набор это отдельный тест: падает один случай, остальные проходят, и в отчёте видно, какой именно. Это главное отличие от цикла внутри теста;
idsзадают понятные имена, иначе в отчёте будутsalary0,salary1. Для сложных объектов это обязательно;- несколько декораторов дают произведение наборов, что удобно для матрицы условий, но легко раздувает число тестов;
pytest.paramсmarksпозволяет пометить отдельный случай как ожидаемо падающий или пропускаемый, не выключая весь тест;- параметризация фикстуры (
@pytest.fixture(params=[...])) прогоняет все тесты, которые её используют, на каждом варианте окружения, например на двух версиях базы; - косвенная параметризация (
indirect=True) передаёт значение в фикстуру, а не в тест, когда параметр нужен на этапе подготовки.
Практический совет: набор данных должен покрывать границы и особые случаи (пусто, ноль, отрицательное, максимум), а не десять похожих значений.
Где спотыкаются
Пишут цикл с проверками внутри одного теста, и при падении непонятно, на каком значении.
Не задают понятные имена и получают нечитаемый отчёт.
Комбинируют три декоратора и получают сотни тестов, которые долго идут и мало добавляют.