Как сделать автоматический вызов фикстуры?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как сделать автоматический вызов фикстуры в Pytest
В Pytest фикстуры можно сделать автоматически вызываемыми, используя параметр autouse=True. Это мощная функциональность, которая позволяет выполнять код фикстуры для каждого теста в её scope (области видимости) без явного указания фикстуры в параметрах тестовой функции или класса.
Основной синтаксис с autouse=True
import pytest
@pytest.fixture(autouse=True)
def auto_fixture():
"""Эта фикстура будет вызываться автоматически для каждого теста."""
print("\n[SETUP] Автоматическая фикстура выполняется")
yield
print("\n[TEARDOWN] Завершение автоматической фикстуры")
def test_example_1():
"""Тест автоматически получит auto_fixture."""
assert 1 + 1 == 2
def test_example_2():
"""Этот тест также получит auto_fixture автоматически."""
assert "hello".upper() == "HELLO"
Ключевые аспекты автоматических фикстур
- Неявное применение: Фикстура с
autouse=Trueприменяется ко всем тестам в её области видимости (scope). Тестам не нужно объявлять её в параметрах. - Контроль областью видимости: Вы можете комбинировать
autouse=Trueс параметромscope, который определяет, как часто фикстура вызывается:scope="function"(по умолчанию) — для каждой тестовой функцииscope="class"— один раз для тестового классаscope="module"— один раз для модуляscope="session"— один раз за сессию выполнения
import pytest
@pytest.fixture(autouse=True, scope="module")
def module_auto_fixture():
"""Вызывается автоматически один раз для модуля."""
print("\n[MODULE SETUP] Инициализация модуля")
yield
print("\n[MODULE TEARDOWN] Очистка модуля")
class TestSuite:
def test_one(self):
"""Использует module_auto_fixture автоматически."""
assert True
def test_two(self):
"""Тоже использует ту же фикстуру (не создаётся заново)."""
assert 1 == 1
Практические сценарии использования
1. Настройка тестового окружения
@pytest.fixture(autouse=True, scope="session")
def setup_test_environment():
"""Автоматическая настройка окружения для всех тестов."""
# Инициализация тестовой БД
init_test_database()
print("Тестовая БД инициализирована")
yield
# Очистка после всех тестов
cleanup_test_database()
print("Тестовая БД очищена")
2. Логирование и мониторинг
@pytest.fixture(autouse=True)
def log_test_execution():
"""Автоматическое логирование начала и окончания каждого теста."""
test_name = request.node.name
print(f"\n[START] Тест: {test_name}")
start_time = time.time()
yield
duration = time.time() - start_time
print(f"[END] Тест: {test_name} | Длительность: {duration:.2f} сек")
3. Мокирование внешних зависимостей
@pytest.fixture(autouse=True)
def mock_external_services():
"""Автоматическое мокирование всех внешних API."""
with patch('module.external_api_call') as mock_api:
mock_api.return_value = {"status": "success"}
yield
Важные рекомендации и ограничения
- Избегайте злоупотребления: Слишком много автоматических фикстур может сделать тесты неявными и сложными для понимания. Используйте их осмотрительно.
- Порядок выполнения: Автоматические фикстуры выполняются до явно объявленных фикстур в пределах той же области видимости.
- Доступ к request: Для получения информации о текущем тесте внутри фикстуры с
autouse=True, добавьте параметрrequest:
@pytest.fixture(autouse=True)
def context_aware_fixture(request):
"""Фикстура с доступом к контексту теста."""
print(f"Выполняется для теста: {request.node.name}")
if "slow" in request.node.keywords:
print("Это медленный тест, применяем особую логику")
yield
Альтернативный подход — использование хуков Pytest. Например, pytest_runtest_setup и pytest_runtest_teardown в файле conftest.py:
# conftest.py
def pytest_runtest_setup(item):
"""Вызывается перед каждым тестом."""
print(f"\nПодготовка теста: {item.name}")
def pytest_runtest_teardown(item, nextitem):
"""Вызывается после каждого теста."""
print(f"Завершение теста: {item.name}")
Заключение
Автоматические фикстуры с autouse=True — это эффективный инструмент для:
- Глобальной настройки/очистки тестового окружения
- Сбора метрик и логирования
- Применения общих моков или заглушек
- Реализации cross-cutting concerns (сквозной функциональности)
Однако важно соблюдать баланс — используйте их для действительно глобальных задач, а для специфической подготовки данных предпочтительнее явные фикстуры, которые делают зависимости теста более очевидными.