Ответ
Фикстуры в pytest — это функции, которые предоставляют предсказуемую, фиксированную среду для тестов. Они используются для подготовки данных, настройки соединений (например, с БД) или создания объектов, необходимых для тестирования.
Принцип работы:
Код фикстуры выполняется до запуска теста, который её запрашивает. Если используется yield, то фикстура разделяется на две части:
- Setup: Код до
yield(подготовка данных). - Teardown: Код после
yield(очистка ресурсов), который выполняется после завершения теста.
Пример:
import pytest
import tempfile
import os
# Фикстура создает временный файл и передает его имя в тест
@pytest.fixture
def temp_file():
# Setup: создаем файл
fp = tempfile.NamedTemporaryFile(delete=False, mode='w+')
fp.write('test data')
fp.close()
yield fp.name # Передаем управление и данные тесту
# Teardown: удаляем файл после теста
os.unlink(fp.name)
# Тест принимает имя фикстуры в качестве аргумента
def test_read_from_temp_file(temp_file):
with open(temp_file, 'r') as f:
content = f.read()
assert content == 'test data'
Ключевые преимущества:
- Переиспользование кода: Одна фикстура может использоваться во многих тестах.
- Изоляция тестов: Каждый тест получает свой собственный экземпляр фикстуры (по умолчанию).
- Управление ресурсами: Гарантированная очистка ресурсов благодаря
yield. - Гибкость: Область видимости фикстуры (
scope) можно настроить на уровне функции, класса, модуля или всей сессии.
Ответ 18+ 🔞
Слушай, а вот эти ваши фикстуры в pytest — это же просто песня, блядь! Представь себе: ты пишешь тесты, а тебе каждый раз надо одно и то же говно подготавливать — базу накатить, файлик создать, объект сконфигурировать. Так вот, чтобы не повторяться, как попугай ёбаный, и придумали фикстуры.
Это, по сути, такие функции-обслуги. Они всё за тебя делают до того, как твой тест начнётся. А если использовать yield, так они ещё и приберутся после, как заботливая тётя Зина, которая за тобой тарелки моет. Охуенно же!
Смотри, как это выглядит на практике. Вот тебе классический пример с временным файлом:
import pytest
import tempfile
import os
# Вот она, мать её, фикстура!
@pytest.fixture
def temp_file():
# Эта часть — setup, подготовка. Создаём файл.
fp = tempfile.NamedTemporaryFile(delete=False, mode='w+')
fp.write('test data')
fp.close()
yield fp.name # А вот тут мы передаём управление тесту и кидаем ему имя файла.
# А эта часть — teardown, разбор полётов. Файл удаляем. Выполнится ПОСЛЕ теста.
os.unlink(fp.name)
# А вот тест, который эту фикстуру жрёт.
def test_read_from_temp_file(temp_file):
with open(temp_file, 'r') as f:
content = f.read()
assert content == 'test data'
Видишь магию? Тесту похуй, откуда файл взялся. Он просто его получил, проверил и успокоился. А вся грязная работа — создание и удаление — осталась за скобками, в фикстуре. Красота, ёпта!
И главные плюсы, которые просто выносят мозг:
- Не повторяйся, мудила! Написал фикстуру один раз — юзай в сотне тестов.
- Изоляция — наше всё. По умолчанию каждый тест получает свою свеженькую копию данных, чтобы они друг другу не мешали, как пьяные соседи на кухне.
- Ресурсы под контролем. С
yieldты точно знаешь, что всё, что открыл, — закроется. Никаких утечек. - Гибкость пиздец. Можно сделать так, чтобы фикстура жила на протяжении одного теста, всего класса, модуля или даже всей тестовой сессии. Это через параметр
scopeнастраивается.
В общем, вещь архиполезная. Сначала кажется, что лишняя сущность, а потом без неё жить не можешь, как без кофе по утрам.