Сообщить об ошибке.

Фикстура как фабрика данных для тестов pytest

Шаблон "фабрика как фикстура" может помочь в ситуациях, когда результат, возвращаемый фикстурой используется много раз в отдельном тесте. Суть в том, чтобы НЕ возвращала данные из фикстуры напрямую, а возвращать функцию, которая будет генерировать данные в тестовой функции по мере необходимости. Другими словами, возвращаемая фикстурой функция может быть вызвана в тесте неоднократно.

В фабрики, аргументы могут передаваться по мере необходимости:

@pytest.fixture
def make_customer_record():
    def _make_customer_record(name):
        """Создание тестового пользователя"""
        return {"name": name, "orders": []}

    # возвращаем функцию из фикстуры
    return _make_customer_record

# тест запрашивает фабрику-фикстуру `make_customer_record`
def test_customer_records(make_customer_record):
    # по мере необходимости создаем временных 
    # пользователей для проведения тестов
    customer_1 = make_customer_record("Lisa")
    customer_2 = make_customer_record("Mike")
    customer_3 = make_customer_record("Meredith")
    ...

Если необходимо управлять данными, которые создаются фабриками (например, в случае с базой данных), то фикстура легко справиться с такой задачей. В следующем примере, по завершении теста, будут очищены созданные записи в БД:

@pytest.fixture
def make_customer_record():
    # список для хранения созданных тестовых записей
    created_records = []

    def _make_customer_record(name):
        # создание тестовой записи в БД
        record = models.Customer(name=name, orders=[])
        # запоминаем созданную запись
        created_records.append(record)
        # возвращаем тестовую запись в БД
        return record

    # возвращаем фабрику фикстуру
    yield _make_customer_record

    # очищаем БД от тестовых записей
    for record in created_records:
        record.destroy()

# тест запрашивает фабрику-фикстуру `make_customer_record`
def test_customer_records(make_customer_record):
    # по мере необходимости создаем временных 
    # пользователей для проведения тестов
    customer_1 = make_customer_record("Lisa")
    customer_2 = make_customer_record("Mike")
    customer_3 = make_customer_record("Meredith")