В проекте pytest тест не запрашивает фикстуру явно, но она всё равно запускается. Как pytest определяет, что эта фикстура обязательна для такого теста?
Так происходит, если фикстура объявлена с параметром autouse=True и область её видимости охватывает данный тест. pytest автоматически добавляет такую фикстуру в зависимости теста, даже если её имя не указано в аргументах тестовой функции.
При этом фикстуры, от которых зависит autouse-фикстура, также выполняются для затронутых тестов. Это удобно для обязательной подготовки среды, но повышает риск скрытых зависимостей и неожиданных побочных эффектов.
Традиционный подход к подготовке тестов часто использует общий setup-код, который выполняется перед каждым тестом или группой тестов. Такой код упрощает повторяющуюся настройку, но может быть неочевиден при чтении отдельного теста.
Фикстуры pytest разделяют подготовку данных, управление ресурсами и зависимости между тестовыми компонентами. Режим autouse появился как способ явно выразить: определённая подготовка обязательна для всех тестов в заданной области, поэтому её не нужно повторять в сигнатурах тестов.
Тест может не содержать имени фикстуры, но всё равно зависеть от неё через автоматическое включение. Например, autouse-фикстура может очищать базу данных, устанавливать переменные окружения или включать режим подмены внешнего сервиса.
Если разработчик не знает об этой зависимости, тест становится труднее понять и запустить отдельно. Кроме того, тяжёлая autouse-фикстура увеличивает время выполнения множества тестов, а её побочные эффекты могут влиять на порядок и изоляцию проверок.
При сборе тестов pytest анализирует доступные фикстуры и их области видимости. Фикстура с autouse=True автоматически включается в набор зависимостей каждого подходящего теста внутри своей области: функции, класса, модуля, пакета или всей сессии — в зависимости от значения scope.
Минимальный пример:
Тест не запрашивает set_test_mode явно, но pytest всё равно выполняет её перед тестом. После теста pytest завершает фикстуру согласно её жизненному циклу; для фикстуры функции это происходит после каждого теста, а для более широкой области — после завершения соответствующей области.
Важно различать область действия и автоматичность. autouse=True определяет, нужно ли включать фикстуру без явного запроса, а scope — как часто создавать и завершать её экземпляр. Фикстура с областью session может затронуть весь запуск, тогда как фикстура с областью function создаётся отдельно для каждого теста.
Если autouse-фикстура сама принимает другую фикстуру, эта зависимость также будет разрешена автоматически для тех тестов, к которым применяется исходная autouse-фикстура. Поэтому небольшая на вид автоматическая настройка может неявно запускать целую цепочку подготовки.
Автоматические фикстуры подчиняются обычному разрешению фикстур: учитываются расположение теста, conftest.py, область видимости и переопределения. Фикстура, объявленная на уровне каталога, обычно применяется к тестам в этом каталоге и его подкаталогах, если более локальное объявление не изменяет разрешение имени.
Практическое правило: autouse стоит использовать для действительно обязательного и дешёвого контекста — например, для гарантированного сброса состояния или установки общего режима. Если зависимость важна только для части тестов, явное указание фикстуры в сигнатуре обычно делает тест понятнее и уменьшает скрытую связанность.
В проекте интеграционных тестов была autouse-фикстура, которая перед каждым тестом очищала таблицы и поднимала транзакционный контекст. Несколько быстрых тестов конфигурации не работали с базой, но всё равно запускали эту фикстуру, из-за чего локальный прогон занимал значительно больше времени.
Рассматривались два варианта. Первый — оставить автоматическую фикстуру: это сохраняло единое правило изоляции, но скрывало стоимость запуска. Второй — убрать autouse и добавить фикстуру только в тесты, которым нужна база: это ускоряло тесты и делало зависимости явными, но требовало дисциплины и ревью новых тестов.
Выбрали второй вариант для независимых тестов конфигурации, а автоматическую фикстуру сохранили только в отдельном каталоге интеграционных тестов. В результате быстрые проверки перестали поднимать базу, а обязательная изоляция сохранилась там, где она действительно нужна.
Нет. Она действует только в доступной ей области видимости. Фикстура в локальном conftest.py обычно распространяется на тесты своего каталога и вложенных каталогов, а фикстура, объявленная внутри тестового класса, ограничена соответствующим классом. Кроме того, тест может использовать другую фикстуру с тем же именем из-за правил разрешения и переопределения.
Нет, такого глобального эффекта нет. Зависимость выполняется автоматически только в контексте тех тестов, для которых была активирована исходная autouse-фикстура. Поэтому обычная фикстура, запрошенная autouse-фикстурой, не начинает запускаться сама по себе в других тестах.
Нет. Отсутствие имени в сигнатуре не означает отсутствия зависимости: autouse-фикстура может изменять окружение, состояние базы, регистрацию обработчиков или поведение моков. При анализе изоляции и причин падения нужно учитывать граф фикстур, включая автоматические узлы и их зависимости.