Arzamasov
@Arzamasov
Python Developer.

Возможна ли фикстура для отката БД после каждого теста?

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

Примерный скелет необходимой фикстуры:
@pytest_asyncio.fixture(autouse=True)
async def start_transaction(app: FastAPI) -> None:
    """Фикстура для отката базы данных после каждого теста."""
    async with app.container.db().bind.transaction() as tx:
        ...
        yield app.container.db()
        ....
        try:
            await tx.raise_rollback()
        except Exception as ex:
            await tx.raise_rollback()


Фикстура проходит без ошибок и в каждом тесте, и идет всё как надо: фикстура -> yield -> тест -> фикстура. Но БД она не откатывает.
Предполагаю, что это связано с разными коннектами к БД ( у фикстуры и у функции разные коннекты к БД).
Если кто-то решал данные вопрос, подскажите.
  • Вопрос задан
  • 221 просмотр
Пригласить эксперта
Ответы на вопрос 1
@Alex_At_Net
Обращайтесь, помогу - https://t.me/codecraft_phd
Соединение к базе, конечно, надо шарить. Иначе вы действительно открываете транзакцию в одном соединении, а тестируете в другом.

Другая проблема, которую вы упомянули, это наложение тестов друг на друга. Использование транзакций, в теории, создает версии таблиц, которые индивидуальны для соединения. На практике, более-меннее сложные изменения требуют блокировки таблиц - в результате транзакции все равно будут тормозить друг друга.

Я бы решал это проблему через несколько версий тестовой базы (database pool). Когда тест начинается, ему назначается база и открывается транзакция (если есть возможность шарить соединение), либо просто база ресетится на начальное состояние через скрипт инициализации.

Таким образом, тесты работают паралельно и независимо.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы