Для чего нужны фикстуры в pytest
Что проверяют
Понимаете ли вы, что фикстуры это управление зависимостями теста, а не просто общий код подготовки.
Как отвечать
Фикстура готовит то, что нужно тесту, и убирает за собой. Тест объявляет зависимость аргументом, pytest сам её создаёт и передаёт.
@pytest.fixture
def db_session(postgres_url):
session = Session(create_engine(postgres_url))
yield session # всё до yield подготовка, после очистка
session.rollback()
session.close()Что делает их сильнее обычных функций подготовки:
- область видимости:
functionпо умолчанию, но бываетmodule,class,session. Дорогой ресурс вроде контейнера с базой поднимают один раз на всю сессию, а лёгкие данные создают на каждый тест; - очистка через
yield: код послеyieldвыполняется даже при падении теста, поэтому за собой убирается всегда; - композиция: одна фикстура принимает другую аргументом, и получается граф зависимостей, который pytest разрешает сам;
- автоприменение:
autouse=Trueдля того, что нужно всем тестам, например подмены времени; - параметризация:
params=[...]прогоняет один и тот же тест на нескольких вариантах окружения; - общий файл
conftest.py: фикстуры оттуда видны всем тестам каталога без импортов; - встроенные:
tmp_pathдля временных файлов,monkeypatchдля подмен,capsysдля перехвата вывода.
Практическое правило: фикстура должна давать готовый к работе объект, а не набор шагов, и не должна содержать проверок. Проверки живут в тесте, иначе непонятно, что именно упало.
Где спотыкаются
Делают одну огромную фикстуру на всё и получают тесты, зависящие от лишнего.
Ставят широкую область видимости для изменяемых данных, и тесты начинают влиять друг на друга через общее состояние.
Кладут assert внутрь фикстуры, из-за чего падение выглядит как ошибка подготовки, а не как несостоявшаяся проверка.