О фикстурах
См. также
См. также
Фикстуры pytest разработаны с учётом явного объявления, модульности и масштабируемости.
Что такое фикстуры
В тестировании фикстура предоставляет определённый, надёжный и согласованный контекст для тестов. Он может включать окружение (например, базу данных, настроенную с известными параметрами) или содержимое (например, набор данных).
Фикстуры определяют шаги и данные, составляющие фазу подготовки теста (см. Структура теста). В pytest это функции, которые вы определяете для этой цели. Их также можно использовать для определения фазы действия теста; это эффективный приём для разработки более сложных тестов.
Сервисы, состояние или другие рабочие окружения, созданные фикстурами, доступны тестовым функциям через аргументы. Для каждой фикстуры, используемой тестовой функцией, в её определении обычно указывается параметр (названный в честь фикстуры).
Сообщить pytest, что определённая функция является фикстурой, можно с помощью декоратора @pytest.fixture. Вот простой пример того, как может выглядеть фикстура в pytest:
import pytest
class Fruit:
def __init__(self, name):
self.name = name
def __eq__(self, other):
return self.name == other.name
@pytest.fixture
def my_fruit():
return Fruit("apple")
@pytest.fixture
def fruit_basket(my_fruit):
return [Fruit("banana"), my_fruit]
def test_my_fruit_in_basket(my_fruit, fruit_basket):
assert my_fruit in fruit_basket
Тесты не ограничены использованием только одной фикстуры. Они могут зависеть от любого количества фикстур, а фикстуры, в свою очередь, могут использовать другие фикстуры. Именно здесь система фикстур pytest раскрывает свои возможности.
Преимущества перед функциями настройки и очистки в стиле xUnit
Фикстуры pytest значительно лучше классического подхода xUnit с функциями настройки и очистки:
- у фикстур есть явные имена, и они активируются, когда тестовые функции, модули, классы или целые проекты объявляют об их использовании.
- фикстуры реализованы модульно: каждое имя фикстуры вызывает функцию фикстуры, которая сама может использовать другие фикстуры.
- управление фикстурами масштабируется от простого модульного до сложного функционального тестирования: можно параметризовать фикстуры и тесты в соответствии с конфигурацией и параметрами компонентов, а также повторно использовать фикстуры в пределах функции, класса, модуля или всего сеанса тестирования.
- логикой очистки можно легко и безопасно управлять независимо от количества используемых фикстур, без необходимости вручную тщательно обрабатывать ошибки или скрупулёзно контролировать порядок добавления шагов очистки.
Кроме того, pytest по-прежнему поддерживает Как реализовать настройку в стиле xUnit. Вы можете сочетать оба подхода и постепенно переходить от классического стиля к новому, если захотите. Можно также начать с уже существующего стиля unittest.TestCase.
Ошибки фикстур
pytest старается выстроить все фикстуры для данного теста в линейном порядке, чтобы определить, какая фикстура выполняется первой, второй, третьей и так далее. Однако если более ранняя фикстура столкнётся с проблемой и вызовет исключение, pytest прекратит выполнение фикстур для этого теста и отметит тест как содержащий ошибку.
Однако отметка об ошибке не означает, что тест завершился неудачно. Она означает лишь, что тест даже не удалось запустить из-за проблемы с одной из его зависимостей.
Вот почему для каждого теста полезно исключать как можно больше ненужных зависимостей. Так проблема, не связанная с тестом, не помешает нам получить полное представление о том, что может работать или не работать.
Вот краткий пример, который поможет это объяснить:
import pytest
@pytest.fixture
def order():
return []
@pytest.fixture
def append_first(order):
order.append(1)
@pytest.fixture
def append_second(order, append_first):
order.extend([2])
@pytest.fixture(autouse=True)
def append_third(order, append_second):
order += [3]
def test_order(order):
assert order == [1, 2, 3]
Если по какой-либо причине в order.append(1) есть ошибка и она вызывает исключение, мы не сможем узнать, есть ли проблемы также в order.extend([2]) или order += [3]. После того как append_first вызовет исключение, pytest не будет запускать другие фикстуры для test_order и даже не попытается запустить сам test_order. Выполнены будут только order и append_first.
Примечание об очистке фикстур
pytest не выполняет специальную обработку сигналов SIGTERM и SIGQUIT (сигнал SIGINT обрабатывается средой выполнения Python стандартным образом через KeyboardInterrupt), поэтому фикстуры, управляющие внешними ресурсами, которые важно освободить при завершении процесса Python (по этим сигналам), могут привести к утечке ресурсов.
pytest не обрабатывает эти сигналы для очистки фикстур, поскольку обработчики сигналов являются глобальными, и их изменение может повлиять на выполняемый код.
Если фикстуры в вашем наборе тестов требуют особого внимания при завершении работы в таких ситуациях, возможный обходной путь описан в этом комментарии в системе отслеживания ошибок.
© 2015–2026 Holger Krekel and pytest-dev team
Licensed under the MIT License.
https://docs.pytest.org/en/stable/explanation/fixtures.html