В практической ситуации тест находится во вложенном каталоге, где одноимённые фикстуры объявлены в двух conftest.py. Какую фикстуру выберет pytest?
pytest выберет фикстуру из ближайшего к тесту conftest.py. Фикстура из более близкого каталога перекрывает одноимённую фикстуру из родительского каталога.
Система fixtures в pytest появилась как способ отделить подготовку окружения теста от его логики и сделать эту подготовку повторно используемой. Размещение общих фикстур в conftest.py позволяет автоматически предоставлять их тестам без явных импортов.
Иерархия каталогов добавляет область видимости: общие настройки можно разместить выше, а специализированные — переопределить ближе к конкретной группе тестов.
Например, в tests/conftest.py определена фикстура подключения к общей тестовой базе, а в tests/api/conftest.py — фикстура с тем же именем для изолированной базы API. Тест из tests/api не получит обе фикстуры и не выберет вариант случайно.
Если разработчик ошибочно рассчитывает на родительскую фикстуру, тест может начать работать с другим ресурсом: использовать иной URL, базу данных или настройки авторизации. Это приводит к неожиданным результатам и усложняет диагностику.
При разрешении фикстуры pytest рассматривает пространство имён от теста наружу: сначала локальные определения тестового модуля, затем conftest.py в текущем каталоге, затем файлы в родительских каталогах. Используется первое найденное определение с нужным именем.
Минимальный пример:
Тест из tests/api получит значение "клиент API". pytest не объединяет тела двух одноимённых фикстур и не вызывает родительскую автоматически.
Определение фикстуры непосредственно в тестовом модуле обычно имеет ещё более локальную область видимости и также перекрывает вариант из conftest.py. Фикстуры, предоставленные плагинами, рассматриваются как внешний источник и не должны перекрывать локальное определение с тем же именем.
Важное ограничение: поиск зависит от положения теста в дереве коллекции, а не от того, где физически импортирована функция теста. Перемещение теста в другой каталог может изменить используемую фикстуру без изменения самого тестового кода.
Переопределение удобно для специализации, но опасно при совпадении имён случайно. Для разных ресурсов лучше использовать разные имена, а намеренное переопределение фиксировать в документации или небольшим тестом конфигурации.
В проекте общая фикстура database создавала PostgreSQL-схему для интеграционных тестов. Для тестов платежного API потребовалась база с дополнительными таблицами, поэтому в tests/payments/conftest.py появилась фикстура с тем же именем.
Рассматривались три варианта. Переименовать фикстуру в payments_database было наиболее явно, но потребовало изменить множество тестов. Импортировать нужную фикстуру вручную было хуже: это обходило стандартную модель видимости pytest и усложняло управление зависимостями. Намеренно переопределить database в дочернем conftest.py было компактно, но создавало риск неправильных ожиданий у новых разработчиков.
Выбрали локальное переопределение, потому что платежные тесты должны были прозрачно получать специализированную базу под прежним именем. В conftest.py добавили комментарий о назначении переопределения и отдельный тест, проверяющий характерную настройку схемы. В результате общие тесты сохранили прежнее окружение, а платежные автоматически стали использовать специализированное.
conftest.py?Нет. Выбирается одно определение — ближайшее по области видимости. Тело родительской фикстуры не выполняется автоматически и не становится частью дочерней.
Если нужно использовать общую подготовку и добавить специализацию, безопаснее вынести общую часть в фикстуру с другим именем, а локальную сделать зависимой от неё. Иначе получить «родительскую» реализацию по тому же имени напрямую нельзя.
Да, это возможно. pytest разрешает фикстуры относительно узла теста в дереве каталогов, поэтому после перемещения тест может оказаться в другой цепочке conftest.py.
Такое поведение особенно опасно при одинаковых именах фикстур в разных каталогах. При реорганизации тестов нужно проверять не только импорты, но и доступные локальные определения фикстур.
Локальная фикстура обычно имеет приоритет над фикстурой, предоставленной плагином: pytest сначала ищет определения в тестовом модуле и каталогах проекта, а затем использует внешние источники.
Конфликт всё равно может быть проблемой, если плагин ожидает конкретную семантику имени. Поэтому распространённые имена фикстур следует переопределять намеренно, проверяя документацию плагина и фактическую цепочку зависимостей.