Какой порядок поиска по фикстурам?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Порядок разрешения фикстур в Pytest
В Pytest разрешение зависимостей фикстур происходит на этапе компиляции тестовой сессии, до выполнения самих тестов. Когда Pytest встречает тестовую функцию или другую фикстуру, которая требует определенные фикстуры в качестве аргументов, он строит граф зависимостей и разрешает их в строго определенном порядке.
Основные правила порядка разрешения
- Сверху вниз по цепочке зависимостей — когда фикстура A зависит от фикстуры B, сначала создается экземпляр B.
- От более широкой области видимости к более узкой — фикстуры с большей областью видимости (scope) создаются раньше.
- Автоматические фикстуры (autouse=True) выполняются раньше явно запрошенных в той же области.
Детальная последовательность
Рассмотрим на практическом примере:
import pytest
# Фикстуры с разными scope и зависимостями
@pytest.fixture(scope="session")
def session_fixture():
print("\nSETUP session_fixture")
yield
print("\nTEARDOWN session_fixture")
@pytest.fixture(scope="module")
def module_fixture(session_fixture): # Зависит от session_fixture
print("\nSETUP module_fixture")
yield
print("\nTEARDOWN module_fixture")
@pytest.fixture(scope="class", autouse=True)
def autouse_class_fixture():
print("\nSETUP autouse_class_fixture (autouse)")
yield
print("\nTEARDOWN autouse_class_fixture (autouse)")
@pytest.fixture(scope="function")
def function_fixture(module_fixture): # Зависит от module_fixture
print("\nSETUP function_fixture")
yield
print("\nTEARDOWN function_fixture")
def test_example(function_fixture):
print("\nRUNNING test_example")
assert True
Порядок выполнения для этого теста будет:
- session_fixture (scope="session") — самая широкая область
- module_fixture (scope="module") — зависит от session_fixture
- autouse_class_fixture (scope="class", autouse=True) — автоматическая, область класса
- function_fixture (scope="function") — явно запрошенная тестом
- test_example — сам тест
Вывод в консоли:
SETUP session_fixture
SETUP module_fixture
SETUP autouse_class_fixture (autouse)
SETUP function_fixture
RUNNING test_example
TEARDOWN function_fixture
TEARDOWN autouse_class_fixture (autouse)
TEARDOWN module_fixture
TEARDOWN session_fixture
Ключевые принципы
- Область видимости (scope) приоритетнее зависимостей — если фикстура A имеет scope="session", а фикстура B имеет scope="function" и зависит от A, то A будет создана раньше B независимо от порядка объявления.
- Autouse фикстуры выполняются перед явно запрошенными фикстурами той же области видимости.
- Порядок teardown обратный порядку setup — принцип LIFO (Last In, First Out).
Специальные случаи
# Конфликт областей видимости
@pytest.fixture(scope="module")
def fixture_a():
return "A"
@pytest.fixture(scope="function")
def fixture_b(fixture_a): # ОШИБКА: function-фикстура не может зависеть от module-фикстуры
return f"B depends on {fixture_a}"
Важное ограничение: Фикстура не может зависеть от фикстуры с более узкой областью видимости. Это логично, так как фикстура с большей областью живет дольше и не может быть создана после того, от которого зависит.
Практические рекомендации
- Используйте явные зависимости вместо неявных (autouse), где это возможно
- Минимизируйте области видимости — используйте самую узкую допустимую область
- Избегайте циклических зависимостей — Pytest обнаружит их и выдаст ошибку
- Помните об ограничениях — зависимость всегда идет от более широкой области к более узкой
Понимание порядка разрешения фикстур критически важно для:
- Предсказуемого управления состоянием
- Эффективного использования ресурсов
- Избежания трудноотлаживаемых ошибок, связанных с порядком инициализации
- Создания читаемых и поддерживаемых тестовых сценариев
Правильное использование порядка фикстур позволяет создавать эффективные, изолированные и быстрые тесты с четким разделением ответственности между компонентами системы тестирования.