Программирование PythonТестированиеИнженер по автоматизации тестирования на Python

Рассмотрите сессионную фикстуру pytest, параметризованную двумя значениями: сколько экземпляров фикстуры по...

Рассмотрите сессионную фикстуру pytest, параметризованную двумя значениями: сколько экземпляров фикстуры получит тестовая сессия?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Тестовая сессия получит два экземпляра фикстуры — по одному для каждого значения параметра. Область действия session означает повторное использование экземпляра всеми подходящими тестами, но не объединяет разные параметры в один экземпляр.

Исторический контекст

Параметризация появилась как способ прогонять один набор тестов через несколько вариантов окружения, конфигурации или входных данных без копирования тестового кода. Фикстуры добавляют к этому управляемое создание и освобождение ресурсов.

Сочетание параметризации с областью действия позволяет, например, один раз за время использования конкретного параметра создать подключение или подготовленное окружение и затем передать его нескольким тестам.

Постановка проблемы

Распространённая ошибка — считать, что session всегда означает ровно один объект на весь запуск pytest. Если фикстура параметризована, её кэш различает значения параметра, поэтому общий ресурс для первого значения не может автоматически использоваться как ресурс для второго.

Неверное понимание приводит к лишним ожиданиям: тесты могут создать ресурс дважды, а изменения состояния одного параметризованного экземпляра не должны рассматриваться как изменения другого. Если ресурс дорогой, это также влияет на время тестового запуска.

Подробное решение

Для каждого значения параметра pytest создаёт отдельный экземпляр фикстуры. Все тесты, запущенные с одним и тем же значением, используют соответствующий экземпляр повторно в пределах его сессионной области.

Минимальная схема:

import pytest @pytest.fixture(scope="session", params=["sqlite", "postgres"]) def database(request): resource = connect(request.param) yield resource resource.close() def test_query(database): assert database.is_ready()

Здесь тест будет выполнен для двух параметров, а фикстура создаст отдельный ресурс для sqlite и отдельный ресурс для postgres. Завершение каждого экземпляра происходит после того, как pytest закончит использовать его в рамках соответствующей области и параметра; порядок группировки тестов определяется pytest.

Важно различать параметризацию фикстуры и параметризацию самого теста: первая создаёт варианты фикстуры, а каждый тест, зависящий от неё, получает запуск для каждого доступного параметра. При большом числе параметров количество запусков и стоимость подготовки ресурсов растут.

Компромисс такой: широкая область действия уменьшает число дорогих подготовок, но увеличивает риск общего изменяемого состояния. Если изоляция важнее стоимости ресурса, лучше выбрать более узкую область действия или явно сбрасывать состояние перед каждым тестом.

Ситуация из практики

Команда тестирует слой работы с базой данных на двух движках. Сессионную фикстуру параметризовали названиями движков и обнаружили, что миграции выполняются дважды.

Вариант с одной непараметризованной фикстурой потребовал бы вручную переключать движок внутри тестов. Это уменьшило бы число подготовок, но сделало бы тесты менее прозрачными и повысило риск случайно проверить только один вариант.

Вариант с function-областью дал бы максимальную изоляцию, однако создавал бы базу заново для каждого теста. Выбранная параметризованная фикстура с областью session сохранила явные отдельные прогоны для обоих движков и ограничила подготовку одним экземпляром на каждый параметр.

Что кандидаты часто упускают

  1. Может ли один экземпляр сессионной фикстуры обслужить оба значения параметра?

Нет. Значение параметра является частью идентичности экземпляра фикстуры. Даже при session pytest создаёт отдельный экземпляр для каждого параметра, иначе результаты одного варианта могли бы загрязнить другой.

  1. Означает ли два параметра ровно два запуска каждого теста?

Да, если тест прямо или косвенно зависит от этой фикстуры и оба параметра доступны. Каждый такой тест получает отдельный вариант выполнения для каждого значения; при наличии дополнительной параметризации варианты перемножаются.

  1. Что произойдёт, если сессионная фикстура изменяет объект, передаваемый тестам?

Изменения будут видны последующим тестам, использующим тот же параметризованный экземпляр. Поэтому сессионная фикстура подходит для неизменяемого или тщательно контролируемого состояния, но опасна для общего изменяемого объекта без сброса состояния; иначе порядок тестов может повлиять на результат.