Spec-Zone.ru › pytest

О фикстурах

См. также

Как использовать фикстуры

См. также

Справочник по фикстурам

Фикстуры 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.

Ещё один хороший подход — поместить файлы с данными в каталог tests. Для управления этим аспектом тестирования также доступны плагины сообщества, например pytest-datadir и pytest-datafiles.

Примечание об очистке фикстур

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API