Модульное тестирование в Java упрощается с помощью таких библиотек, как JUnit и например Mockito , но для интеграционного тестирования нет такой же панацеи. Наряду с вашими имитированными модульными тестами, интеграционные тесты важны для обеспечения правильной работы вашего программного обеспечения при доступе к внешним службам. Ранее мы применяли различные подходы к решению этой проблемы, такие как:
- Внедрение сервиса
- Запуск службы
- Запуск контейнера Docker для службы
Встраивание сервиса может быть сложным (особенно если это не Java). Запуск их напрямую или удаленно добавляет значительную работу по настройке, обслуживанию и обеспечению доступности для всех разработчиков и вашей службы непрерывной интеграции. Запуск контейнера Docker для сервиса был нашим предпочтительным методом, но их настройка локально и как часть сборки CI, похоже, не соответствует фундаментальному подходу к тестированию. Это было для нас общей и неприятной болевой точкой.
Испытательные контейнеры
Недавно мы перешли на использование Тестовых контейнеров для решения этой проблемы. Test Containers – это лицензированный проект с открытым исходным кодом MIT для запуска контейнера Docker для тестирования JUnit.
Выгоды
Это имеет ряд преимуществ по сравнению с нашими предыдущими подходами. Во-первых, мы проводим тесты с реальным экземпляром сервиса, а не с какой-то поддельной или встроенной версией, которая может вести себя по-другому. Поскольку контейнеры запускаются только для теста, они изолированы от других тестов и становятся намного более воспроизводимыми. Настройка и настройка выполняются в тестовом классе, которому они принадлежат. Это также позволяет вам легко повторить тест с различными версиями сервиса, позволяя вам правильно определить совместимость и проверить, что новые версии сервисов не требуют изменений в вашем собственном коде.
Варианты использования
Этот метод интеграционного тестирования может быть легко применен к нескольким вариантам использования, некоторые из которых имеют более специализированную поддержку:
- Базы данных
- Услуги по ведению журнала
- Веб-сервисы
- Сложные мультисервисные взаимодействия с использованием Docker Compose
- Тестирование пользовательского интерфейса с помощью Selenium
Пример
В следующем примере показано, как настроить интеграционный тест для Redis.
import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; import redis.clients.jedis.Jedis; public class RedisIntegrationTest { private static final String DOCKER_IMAGE = "redis:3.2.9"; private final Jedis jedis; @Rule // 1 public static GenericContainer redis = new GenericContainer(DOCKER_IMAGE).withExposedPorts(6379); // 2, 3 @Before public void setUp() throws Exception { Jedis jedis = new Jedis(redis.getContainerIpAddress(), redis.getMappedPort(6379)); // 4 } @Test public void yourTest() { //Your test code here } }
@Rule
Запускает новый контейнер для каждого теста, вы можете изменить на@ClassRule
для одного контейнера для тестового класса.- Он также поддерживает использование Dockerfiles или файлов Docker Compose для нестандартных, не опубликованных контейнеров с помощью
DockerComposeContainer
. - Другая стандартная конфигурация docker, например
.с объемом (), (), с Env(), withCommand()
доступны. - Получите нужную вам конфигурацию из объекта
Generic Container
.
Недостатки
Ни одного! Хорошо, может быть, есть некоторые недостатки, но мы думаем, что они того стоят:
- Вам нужен docker, доступный для запуска тестов. (т.е. на вашем локальном устройстве и на сервере CI), но кто этого не делает?
- Вам необходимо сделать docker доступным (для чего может потребоваться открыть сокет docker)
- Вы должны загрузить изображение, но это необходимо только один раз.
- Поддержка Windows находится только в альфа-версии.
Кредит: Изображение Ричард Норт , проект “Тестовые контейнеры”.
Оригинал: “https://dev.to/committedsw/docker-in-junit-tests-4p4i”