Как реализовать генераторные функции внутри фикстур в pytest для управления их порядком выполнения?
Ответ от нейросети
sobes.tech AI
Что хотят услышать интервьюеры:
Генераторные фикстуры в pytest используют, когда нужно выполнить подготовку до теста и очистку после него. Для этого в фикстуре ставят yield: всё до него выполняется перед тестом, всё после — после завершения теста. Такой подход позволяет явно управлять порядком setup/teardown и удобно комбинировать несколько фикстур.
Определение:
Генераторная фикстура — это фикстура, которая содержит yield и разделяет логику на две части: до yield выполняется подготовка тестового окружения, а после yield — завершающие действия, такие как удаление файлов, закрытие соединений или откат состояния. В pytest код после yield запускается только после завершения теста, даже если тест упал, что делает такие фикстуры удобными для управления порядком выполнения и очисткой ресурсов.
Пример использования:
import pytest
@pytest.fixture
def resource():
print("setup: create resource")
data = {"status": "ready"}
yield data
print("teardown: destroy resource")
def test_example(resource):
assert resource["status"] == "ready"
Если нужно управлять порядком нескольких фикстур, можно сделать их зависимыми друг от друга:
import pytest
@pytest.fixture
def db():
print("setup db")
yield "db"
print("teardown db")
@pytest.fixture
def user(db):
print("setup user using", db)
yield "user"
print("teardown user")
def test_order(user):
assert user == "user"
Пояснение кода:
В первом примере всё до yield выполняется перед запуском теста: создаётся ресурс и подготавливаются данные. Значение после yield передаётся в тест как результат фикстуры. После завершения теста pytest продолжает выполнение фикстуры с места после yield и выполняет очистку.
Во втором примере порядок задаётся зависимостями между фикстурами. Сначала pytest вызывает db, затем user, потому что user зависит от db. После теста teardown выполняется в обратном порядке: сначала user, потом db. Это удобно, когда ресурсы создаются вложенно и освобождать их нужно строго в обратной последовательности.
Ключевые моменты:
yieldв фикстуре делит её на фазу подготовки и фазу очистки.- Код до
yieldвыполняется до теста, код после — после теста. - Если одна фикстура зависит от другой,
pytestвыстраивает порядок выполнения по графу зависимостей. - Очистка после
yieldвыполняется даже при падении теста. - Для сложного порядка лучше явно задавать зависимости между фикстурами, а не рассчитывать на неявное поведение.
- Генераторные фикстуры особенно полезны для ресурсов, которые нужно гарантированно закрыть или удалить.