Зачем pytest рассматривает conftest.py как локальный плагин, а не как обычный модуль тестового проекта?
conftest.py — это локальный плагин pytest: pytest автоматически обнаруживает его при сборке тестов и делает объявленные там фикстуры доступными тестам в соответствующей директории и её подкаталогах. Такой файл не следует использовать как обычный модуль для импорта общих функций или фикстур.
Подход появился для локального размещения тестовой инфраструктуры без явных импортов в каждом тесте. Это позволяет организовать фикстуры по дереву каталогов: общие ресурсы находятся выше, а специализированные переопределения — ближе к конкретным тестам.
Таким образом, pytest отделяет механизм обнаружения тестовой инфраструктуры от обычной архитектуры импортируемых Python-модулей. conftest.py выполняет роль точки расширения pytest, а не публичной библиотеки проекта.
Если импортировать фикстуру напрямую из conftest.py, тест начинает зависеть от способа, которым pytest загрузил этот файл. В разных структурах проекта один и тот же файл может иметь разные пути импорта, что повышает риск дублированной загрузки, циклических импортов, конфликтов имён и ошибок при сборке.
Кроме того, прямой импорт скрывает область действия фикстуры. Читателю теста сложнее понять, откуда она доступна и какое локальное переопределение применит pytest.
Во время сбора тестов pytest загружает conftest.py как плагин, связанный с конкретным каталогом. Фикстуры из него видимы тестам этого каталога и вложенных каталогов, если более близкий conftest.py не переопределяет ту же фикстуру.
Для повторно используемого кода следует разделять роли:
Технически импорт conftest.py иногда возможен, но это не делает такой импорт надёжным контрактом. Главный компромисс — небольшое дублирование объявления фикстуры предпочтительнее неявной зависимости от внутреннего способа загрузки pytest.
В проекте тесты из разных каталогов начали импортировать фабрику из conftest.py. Локально всё работало, но при запуске полного набора pytest обнаружил конфликт модулей: часть тестов ссылалась на объект из одной загрузки файла, а часть — на объект из другой.
Можно было оставить прямые импорты и исправлять пути, но это сохраняло хрупкую зависимость от структуры запуска. Другой вариант — перенести весь conftest.py в общий пакет, однако тогда локальные фикстуры потеряли бы естественную область видимости.
Выбранное решение: фабрику вынесли в обычный импортируемый модуль тестовых утилит, а фикстуры оставили в соответствующих conftest.py. После этого pytest самостоятельно управлял фикстурами, а обычный Python-код импортировался единообразно при любом способе запуска.
Ответ: Нет, обычное дерево видимости pytest направлено от каталога теста к его родительским каталогам, а не к соседним веткам. Если фикстура нужна нескольким независимым каталогам, её следует разместить в общем родительском conftest.py, подключаемом плагине или явно импортируемом модуле с фабрикой.
Ответ: Для тестов дочернего каталога будет выбрана более близкая фикстура. Это позволяет локально переопределять поведение, но создаёт риск неочевидного изменения сценариев, поэтому такие переопределения стоит делать явно и документировать.
Ответ: Да, но тогда pytest не получит её автоматически только из-за наличия функции в модуле. Фикстуру нужно явно подключить или импортировать способом, поддерживаемым выбранной организацией проекта; при этом теряется часть локальной модели видимости conftest.py. Такой вариант оправдан, когда фикстура действительно является общей библиотечной частью тестовой инфраструктуры.