Testcontainers + DB Rider = конец проблем с данными в интеграционных тестах
Если у тебя когда-нибудь “плавали” интеграционные тесты из-за грязной БД — ты знаешь эту боль. Testcontainers решает только половину проблемы: он поднимает чистый контейнер. Но что происходит внутри теста? Как гарантировать предсказуемые данные и стабильные проверки?
Ответ — DB Rider.
Testcontainers для тех, кто не знает, что это
Testcontainers — библиотека для интеграционных тестов, которая позволяет поднимать контейнеры Docker с различными образами (PostgreSQL, Kafka, Redis, MiniO, любые другие контейнеры) прямо в тестах, автоматически и изолированно. Вместо моков или «in-memory» мы можем работать с настоящими сервисами и инфраструктурой, развернутой посредством Docker или другой системой контейнеризации. Контейнеры стартуют перед тестами и автоматически удаляются после выполнения.
Почему именно эта комбинация
- Testcontainer поднимает настоящие базы данных в контейнерах.
- Database Rider обеспечивает простой и декларативный механизм инициализации данных перед тестом.
- Database Rider дает возможность проверить снимок данных после выполнения тестов.
- Вместе они дают полную изоляцию тестов и повторяемость результатов.
- Нет необходимости настраивать дополнительные экземпляры СУБД для проведения интеграционных тестов.
Пример использования Testcontainer и Database Rider
Изменим предыдущий пример, чтобы вместо H2 использовать Testcontainer с PostgreSQL. Для этого нам нужно будет убрать зависимости с H2 и добавить зависимости для TestContainers:
Теперь для того, чтобы правильно подхватывались настройки datasource, мы изменим файл свойств application-test.yml, удалим всё, связанное с h2, и добавим строку подключения к контейнеру с PostgreSQL:
Здесь init-schema.sql - файл скрипта для инициализации схемы БД, который будет выполняться при запуске контейнера:
Чтобы наш тест заработал с использованием TestContainers, нам нужно будет добавить аннотацию @Testcontainers в класс теста.
Еще пара важных моментов:
- Необходимо добавить аннотацию @DBUnit(schema = "public", caseSensitiveTableNames = true) в класс теста, чтобы указать схему базы данных, которую мы хотим использовать для тестов и убрать чувствительность к регистру иначе Database Rider не увидит наши таблицы.
- И вместо @DataJpaTest использовать @SpringBootTest - потому что при использовании @DataJpaTest каждый метод оборачивается в транзакцию, а проверка Database Rider происходит после того как транзакция отменяется, поэтому он не увидит данные, которые были добавлены в таблицу.
Теперь можно запустить тесты и убедиться, что все работает как надо:
Полный код примера доступен по ссылке
Заключение
Комбинация Testcontainers и Database Rider предоставляет:
- Окружение для тестирования, приближенное к продакшену.
- Контроль и предсказуемость состояния БД.
- Скорость создания и модификации интеграционных тестов.
- Гибкость и поддержку сложных сценариев интеграционных тестов.
Используете у себя в проектах Testcontainers? Трудно ли поддерживать сложные сценарии?
Подпишись на мой канал в telegram