Короткий ответ
Фикстура — это функция с декоратором @pytest.fixture, которая подготавливает данные или ресурс для теста (объект, соединение, тестовые данные) и может сама освобождать его после выполнения теста.
Как это работает подробнее
Тест получает фикстуру, просто указав её имя как аргумент функции; pytest по этому имени находит соответствующую фикстуру и вызывает её перед тестом, передавая возвращённое (или yield-нутое) значение автоматически, без явного вызова разработчиком. Если фикстура использует yield, код после yield выполняется как teardown после завершения теста, даже если сам тест упал с ошибкой.
Пример кода
testing_example_293.py
import pytest
@pytest.fixture
def db_connection():
conn = create_test_connection()
yield conn # вот тут тест получает соединение
conn.close() # выполнится после теста — teardown
def test_insert_user(db_connection):
db_connection.execute("INSERT INTO users (name) VALUES ('Ann')")
assert db_connection.execute("SELECT COUNT(*) FROM users").scalar() == 1Что использовать на практике
- Практика. Фикстуры удобны для переиспользуемой подготовки: тестовый клиент API, тестовое соединение с БД, тестовые пользователи — вместо копирования одного и того же кода подготовки в каждый тест. Их можно объявлять в conftest.py, чтобы они были доступны во всех тестах каталога без явного импорта, а также комбинировать одну фикстуру внутри другой для построения более сложного состояния.
Подводные камни
- Риск. Класть в фикстуру слишком много логики и неявных побочных эффектов, из-за чего тест становится непрозрачным — непонятно, что именно подготовлено и почему тест вообще проходит или падает. Забывать про teardown (освобождение ресурса) при использовании return вместо yield, когда ресурс нужно закрывать явно, что приводит к утечке соединений между тестами.