Ответ
В тестировании фикстура — это фиксированное состояние тестового окружения или набор данных, который используется как известная точка отсчета для выполнения тестов. Её цель — обеспечить повторяемость и изоляцию тестов, чтобы они запускались в предсказуемых условиях.
Основные типы фикстур в pytest:
@pytest.fixture— базовая фикстура, создающая объект для передачи в тест.scope='session'— фикстура создается один раз за всю сессию тестирования (например, подключение к БД).scope='module'— создается один раз на модуль.scope='class'— создается один раз на класс тестов.scope='function'(по умолчанию) — создается заново для каждой тестовой функции.autouse=True— фикстура запускается автоматически, без явного указания в аргументах теста.
Практический пример: подготовка и очистка тестовых данных в БД
import pytest
import psycopg2
@pytest.fixture(scope="function")
def test_user(db_connection):
"""Фикстура создает тестового пользователя и удаляет его после теста."""
cursor = db_connection.cursor()
# Setup: создаем пользователя
cursor.execute(
"INSERT INTO users (username, email) VALUES (%s, %s) RETURNING id;",
("test_fixture_user", "test@example.com")
)
user_id = cursor.fetchone()[0]
db_connection.commit()
yield user_id # Передаем ID в тест
# Teardown: удаляем пользователя после теста
cursor.execute("DELETE FROM users WHERE id = %s;", (user_id,))
db_connection.commit()
cursor.close()
def test_user_creation(test_user):
"""Тест использует фикстуру `test_user`, получая ID созданного пользователя."""
# Здесь можно проверить, что пользователь доступен в системе
assert test_user is not None
# После выполнения теста фикстура автоматически выполнит teardown-часть (DELETE).
Фикстуры — это мощный инструмент для управления зависимостями тестов, позволяющий избегать дублирования кода setup/teardown.
Ответ 18+ 🔞
А, фикстуры, блядь! Ну это ж классика, ёпта! Сейчас объясню на пальцах, чтобы даже мартышлюшка поняла.
Представь, ты каждый раз перед тестом, как идиот, вручную настраиваешь одно и то же: базу данных поднимаешь, тестового юзера создаёшь, конфиги читаешь. А потом после теста всё это добро надо ещё и прибрать, чтобы следующий тест не наступил в это говно. Задолбаешься, блядь, через неделю.
Так вот, фикстура — это как твой личный раб-дворецкий для тестов. Ты ему один раз говоришь: «Слушай сюда, ушастый, вот тебе инструкция, как приготовить мне чистенькую тестовую песочницу». А он тебе её каждый раз по первому требованию подаёт, да ещё и после использования сам всё за собой убирает, в рот меня чих-пых! Цель — чтобы тесты были повторяемыми и изолированными, то есть не зависели друг от друга и от погоды на Марсе.
Основные виды этих самых дворецких в pytest:
@pytest.fixture— базовый раб. Сказал «подай объект» — он подал.scope='session'— раб на всю тусовку. Создался один раз в начале (типа подключение к БД) и до конца всех тестов живёт. Экономия — овердохуища.scope='module'— раб на один файл с тестами.scope='class'— раб на один класс. Для любителей ООП.scope='function'(стоит по умолчанию) — самый работящий раб. Для КАЖДОГО теста заново всё готовит. Надёжно, но может быть долго, если он там ядро Linux компилирует.autouse=True— это вообще инициативный хуй. Ты его даже не звал, а он уже всё приготовил и стоит с довольной рожей. Иногда полезно, но чаще — неожиданный пиздец.
Пример из жизни, чтобы не быть пиздаболом:
Допустим, тебе надо потестить что-то с пользователем в базе данных. Без фикстуры ты в каждом тесте пишешь INSERT, а потом забываешь DELETE и вся база превращается в помойку. С фикстурой — красота.
import pytest
import psycopg2
@pytest.fixture(scope="function")
def test_user(db_connection):
"""Фикстура создает тестового пользователя и удаляет его после теста."""
cursor = db_connection.cursor()
# Setup: создаем пользователя
cursor.execute(
"INSERT INTO users (username, email) VALUES (%s, %s) RETURNING id;",
("test_fixture_user", "test@example.com")
)
user_id = cursor.fetchone()[0]
db_connection.commit()
yield user_id # Передаем ID в тест
# Teardown: удаляем пользователя после теста
cursor.execute("DELETE FROM users WHERE id = %s;", (user_id,))
db_connection.commit()
cursor.close()
def test_user_creation(test_user):
"""Тест использует фикстуру `test_user`, получая ID созданного пользователя."""
# Здесь можно проверить, что пользователь доступен в системе
assert test_user is not None
# После выполнения теста фикстура автоматически выполнит teardown-часть (DELETE).
Смотри, какая магия: перед test_user_creation наш дворецкий test_user впендюривает в базу нового юзера и отдаёт тебе его id. Ты спокойно тестируешь. А как только тест кончился — неважно, упал он или прошёл — дворецкий возвращается и выполняет код ПОСЛЕ yield, то есть выпиливает этого юзера из базы. Чистота, блядь, идеальная! Никаких лишних следов.
Короче, фикстуры — это мощнейшая хуйня, чтобы не копипастить одно и то же и не тратить нервы на подготовку и уборку. Выучи — и жизнь станет проще, ёпта.