Параметризованная фикстура pytest предоставляет два значения одному тесту. Сколько тестовых случаев создаст pytest и почему?
Pytest создаст два независимых тестовых случая: по одному для каждого значения фикстуры. Тестовый код выполнится отдельно для каждого параметра, поэтому успешный или неуспешный результат одного случая не превращает их в один общий запуск.
Параметризация появилась как практический способ проверять одну и ту же логику на наборе входных данных без копирования тестовой функции. В pytest она отделяет описание сценария от конкретных значений и поддерживает переиспользование наборов данных через фикстуры.
Параметризованная фикстура особенно полезна, когда нужно менять не только входной аргумент, но и способ подготовки окружения: например, создавать клиента для разных реализаций хранилища.
Если воспринимать два параметра как один запуск с двумя последовательными подготовками, можно ошибочно ожидать один общий результат или общее состояние. Это приводит к неверной проверке количества тестов, смешиванию данных между сценариями и неправильной диагностике падений.
Каждое значение должно рассматриваться как отдельная комбинация условий. Если один вариант завершился ошибкой, pytest обычно продолжит запускать остальные варианты, чтобы показать полный результат набора.
Для каждого значения параметра pytest создаёт отдельную тестовую вариацию. Перед её выполнением создаётся соответствующая фикстура, тест получает её результат, а затем выполняется завершающая обработка фикстуры, если она предусмотрена.
В этом примере pytest соберёт два случая: один для sqlite, другой для postgres. В отчёте они получают разные идентификаторы, обычно содержащие значение параметра, что помогает определить, какой вариант завершился ошибкой.
Параметры тестовой функции и параметры фикстуры комбинируются. Поэтому тест с двумя значениями параметризованной фикстуры и тремя собственными параметрами даст шесть комбинаций, если дополнительные настройки не ограничивают этот набор.
Область действия фикстуры не отменяет разделение по параметрам. Фикстура с более широкой областью может переиспользоваться в рамках соответствующей комбинации и области действия, но разные значения параметра требуют разных экземпляров. Это важно для ресурсов, которые нельзя безопасно переключать между сценариями.
Если параметром является изменяемый объект, pytest не обязан создавать его копию для каждого случая. Изменения такого объекта могут быть видны следующим сценариям, если объект переиспользуется внешним кодом или передан как общий параметр. Для изоляции следует создавать независимые объекты или использовать фабрику.
Команда проверяет слой сохранения данных на двух реализациях хранилища. Вариант с отдельными тестами дублирует проверки и при добавлении третьего хранилища быстро увеличивает объём поддержки. Один общий тест с ручным циклом выглядит короче, но pytest воспринимает его как один тест: нельзя отдельно увидеть падение конкретной реализации, а частичное выполнение затрудняет диагностику.
Параметризованная фикстура устраняет оба недостатка: тест остаётся единым по смыслу, а отчёт содержит отдельный результат для каждого хранилища. Это выбранный вариант, поскольку он сохраняет изоляцию случаев и автоматически расширяется при добавлении нового параметра.
Для дорогостоящих ресурсов можно выбрать более широкую область действия фикстуры, но только если экземпляры безопасно переиспользовать в рамках параметра. Иначе экономия времени запуска создаст скрытую связанность и сделает тесты нестабильными.
Дополнительный вопрос: Создаст ли pytest новый экземпляр фикстуры для каждого теста при одном и том же параметре?
Ответ: Это зависит от области действия фикстуры. Для function-области экземпляр создаётся для каждого тестового случая. Для module, class или session он может быть переиспользован в пределах соответствующей области, но для разных параметров создаются отдельные параметризованные экземпляры.
Дополнительный вопрос: Что произойдёт, если создание фикстуры завершится исключением только для одного параметра?
Ответ: Конкретный тестовый случай будет отмечен как ошибочный или неуспешный в зависимости от места и типа исключения. Остальные параметры обычно запускаются независимо, поэтому ошибка подготовки варианта sqlite не означает автоматический пропуск варианта postgres, если их выполнение не остановлено отдельной настройкой или внешней ошибкой.
Дополнительный вопрос: Как параметризация фикстуры влияет на зависимости этой фикстуры?
Ответ: Для каждого тестового случая pytest разрешает граф зависимостей заново, но использует кэширование в рамках области действия. Зависимость, которая получает параметризованный результат напрямую или косвенно, участвует в соответствующей комбинации; зависимости с более широкой областью действия нельзя безопасно связать с фикстурой, имеющей более узкую область, поскольку это нарушает правила жизненного цикла фикстур.