Ответ
Фикстуры в pytest — это мощный механизм для инжекции зависимостей и управления состоянием тестов. В них следует выносить код, который подготавливает окружение, данные или ресурсы, необходимые для выполнения тестов.
Типичные сценарии для фикстур:
-
Инициализация и очистка внешних зависимостей:
- Подключение к базе данных, кэшу или внешнему API.
- Запуск и остановка Selenium WebDriver, мобильного эмулятора.
- Создание и удаление временных файлов или директорий.
import pytest import sqlite3 import tempfile import os @pytest.fixture def temp_db(): """Создает временную БД в памяти для тестов.""" conn = sqlite3.connect(':memory:') yield conn # Тест использует соединение conn.close() # Очистка после теста @pytest.fixture def config_file(): """Создает временный конфигурационный файл.""" with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: f.write('{"timeout": 10}') yield f.name # Возвращает путь к файлу os.unlink(f.name) # Удаляет файл после теста -
Подготовка тестовых данных:
- Генерация мок-объектов, стабов.
- Заполнение БД фиктивными данными (fixtures).
- Создание сложных объектов доменной модели.
@pytest.fixture def mock_user(): """Возвращает объект пользователя с тестовыми данными.""" return User(id=1, username='test_user', is_active=True) -
Конфигурация тестового окружения:
- Установка параметров (timeout, URL, режимы логирования).
- Пропуск тестов при определенных условиях (например, отсутствие драйвера).
-
Общие шаги для группы тестов:
- Авторизация пользователя перед выполнением сценариев.
- Переход на определенную страницу веб-приложения.
Ключевые параметры фикстур:
scope: Определяет время жизни фикстуры ("function"(по умолчанию),"class","module","session"). Используйтеscope="session"для тяжелых операций (запуск браузера), чтобы не повторять их для каждого теста.autouse=True: Фикстура применяется автоматически ко всем тестам в своей области видимости, без явного вызова.params: Позволяет параметризовать фикстуру, запуская тест несколько раз с разными данными.
Главное правило: Если код setup/teardown повторяется в нескольких тестах — его стоит вынести в фикстуру. Это делает тесты чище, DRY (Don't Repeat Yourself) и упрощает их поддержку.
Ответ 18+ 🔞
А, фикстуры в pytest! Ну это ж, блядь, святое дело, ебать мои старые костыли! Это не просто какой-то там setup-teardown, это целая философия, как не нагородить хуйни в каждом втором тесте.
Представь: ты пишешь тесты, и в каждом из них одно и то же — подключись к базе, создай файлик, сгенерируй тестового юзера. И так двадцать раз. Ну ёпта, это же пиздец какой-то рутины! Вот для этого и придумали фикстуры. Выносишь всю эту подготовительную еблу в одно место, и потом просто тычешь в тест аргументом с таким же названием. Красота, блядь!
Так, где их, эти фикстуры, применять-то, спросишь ты?
-
Всякая инициализация и уборка за собой. Ну, типа, открыл соединение с базой — закрой. Создал временный файл — удали. Запустил браузер — прибей. Чтобы не засирать систему, как последний свин.
import pytest import sqlite3 import tempfile import os @pytest.fixture def temp_db(): """База в памяти. Быстро и чисто.""" conn = sqlite3.connect(':memory:') yield conn # Вот тут тест работает conn.close() # А вот тут мы подтираем за собой @pytest.fixture def config_file(): """Временный конфиг. Создали, отдали, стёрли. Как одноразовый стаканчик.""" with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: f.write('{"timeout": 10}') yield f.name # Путь к файлу — тесту os.unlink(f.name) # Файл — в помойку истории -
Подготовка тестовых данных. Чтобы не копипастить один и тот же словарь или объект на десять страниц. Создал фикстуру
mock_user— и все тесты его юзают. И если надо поменять, меняешь в одном месте, а не бегаешь, как угорелый, по всем файлам.@pytest.fixture def mock_user(): """Вот тебе юзер. Бери и тестируй. Не благодари.""" return User(id=1, username='test_user', is_active=True) -
Настройка окружения. Сказал фикстуре
scope="session", и она один раз за прогон всех тестов что-то тяжёлое поднимет (типа того же браузера), а не будет это делать перед каждым тестом, тратя время и нервы. -
Общие шаги для кучи тестов. Например, перед всеми API-тестами надо залогиниться и получить токен. Выносишь в фикстуру с
autouse=Trueв рамках модуля — и все тесты уже авторизованы. Волшебство, блядь!
Параметры, на которые стоит смотреть:
scope: Это, сука, важно! Не тащи тяжёлую фикстуру сscope="function"(это по умолчанию). Для браузера или подключения к реальной БД ставьscope="session"— один раз на всю сессию тестов. Экономия времени — овердохуища!autouse=True: Включил — и фикстура сама применяется ко всем тестам в своей области видимости. Не надо её явно передавать. Удобно, но опасно — можно не заметить, откуда ноги растут.params: Хочешь прогнать тест на разных данных? Параметризуй фикстуру! Она вернёт разные значения, и тест запустится для каждого.
А главное правило, которое бьёт прямо в глаз: если один и тот же кусок кода setup/teardown повторяется больше одного раза — ты уже мудак, если не выносишь его в фикстуру. Это называется DRY, чувак, Don't Repeat Yourself. Не повторяй себя, а то заебешься потом поддерживать эту копипасту. Фикстуры — твои лучшие друзья в мире тестов, запомни это.