Шаблон "фабрика как фикстура" может помочь в ситуациях, когда результат, возвращаемый фикстурой используется много раз в отдельном тесте. Суть в том, чтобы НЕ возвращала данные из фикстуры напрямую, а возвращать функцию, которая будет генерировать данные в тестовой функции по мере необходимости. Другими словами, возвращаемая фикстурой функция может быть вызвана в тесте неоднократно.
В фабрики, аргументы могут передаваться по мере необходимости:
@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")