Ответ
Фикстуры (fixtures) в pytest — это функции с декоратором @pytest.fixture, предназначенные для подготовки и очистки тестового окружения. Они реализуют паттерн dependency injection, автоматически предоставляя ресурсы тестовым функциям, которые объявляют их в качестве параметров.
Основные преимущества:
- Устранение дублирования кода для setup/teardown.
- Изоляция тестов через управление состоянием.
- Гибкость областей видимости:
function(по умолчанию),class,module,session. - Надёжный teardown через
yieldилиaddfinalizer.
Пример фикстуры с setup и teardown:
import pytest
@pytest.fixture
def database_connection():
# Setup: создание соединения
conn = create_db_connection("test_db")
yield conn # Значение передаётся тесту
# Teardown: закрытие соединения (выполняется после теста)
conn.close()
# Тест использует фикстуру как параметр
def test_insert_user(database_connection):
result = database_connection.execute("INSERT INTO users ...")
assert result.rowcount == 1
Практическое применение:
- Подготовка данных: создание тестовых объектов, заполнение БД.
- Конфигурация: инициализация клиентов API, настройка временных каталогов.
- Мокирование: возвращение заглушек для внешних сервисов.
Фикстуры — это краеугольный камень для построения масштабируемых и поддерживаемых тестовых наборов в pytest.
Ответ 18+ 🔞
Слушай, а вот эти ваши фикстуры в pytest — это ж просто песня, а не фича! Ну реально, как будто тебе личного раба подвезли, который всё за тебя подготовит и потом уберёт, чтобы ты, сука, не заморачивался.
Представь: ты пишешь тест, а тебе надо базу данных поднять, таблицы накатить, тестовые данные засунуть. Без фикстур это выглядит как пиздец: в каждом тесте один и тот же код копипастишь, а если что-то поменялось — иди и во всех ста местах правь, волнение ебать, терпения ноль ебать.
А с фикстурами — красота. Объявляешь один раз эту магическую функцию, навешиваешь @pytest.fixture, и всё, пизда. Теперь любой тест может её просто попросить по имени в параметрах, и pytest сам, как хитрая жопа, всё подставит.
import pytest
@pytest.fixture
def database_connection():
# Вот тут ты делаешь всю грязную работу — setup
conn = create_db_connection("test_db")
yield conn # А это — момент истины, когда ты отдаёшь ресурс тесту
# А вот это выполнится ПОСЛЕ теста, хоть он там обосрись или нет — teardown
conn.close()
def test_insert_user(database_connection):
result = database_connection.execute("INSERT INTO users ...")
assert result.rowcount == 1
Смотри, как элегантно: database_connection — это как будто твой личный дворецкий. Ты в тесте просто говоришь: «Эй, дай-ка сюда соединение с базой». А он тебе уже готовое, тёпленькое, подносит. А после того как ты всё проверил и наговнокодил, он тихонечко зайдёт и всё закроет, чтобы ресурсы не висели. Красота, ёпта!
А самое охуенное — это области видимости (scope). По умолчанию фикстура создаётся заново для каждого теста (function). Но если тебе, например, тяжёлое соединение настраивать — овердохуища времени уходит — можно сделать scope='session'. Тогда эта хуйня создастся один раз на весь прогон тестов и будет переиспользоваться, как последняя сигарета в пачке. Есть ещё class и module — тоже полезные штуки.
Где это реально вставляет мозги в пазлы:
- Подготовка данных. Не надо в каждом тесте создавать юзера
User(name='Вася', email='vasya@pidor.ru'). Объявил фикстуру@pytest.fixture def vasya(): return User(...)и таскай этого Васю по всем тестам. - Конфигурация всякой хуйни. Клиент для АПИ, временная папка для файлов, настройки драйвера браузера — всё это идеальные кандидаты.
- Моки и заглушки. Нужно отрезать тест от внешнего мира? Фикстура может вернуть тебе красивый мок, который делает вид, что он платёжный гейт, а на самом деле просто сосалка.
Короче, если ты пишешь тесты на pytest и не используешь фикстуры — ты, прости, мудак. Это тот самый краеугольный камень, на котором держится вся разумная и поддерживаемая тестовая архитектура. Всё остальное — просто детали.