Как стать автором
Обновить

Интеграционные тесты для Java с помощью TestContainers. Меньше безумия, больше порядка, и всё это автоматически

Время на прочтение 9 мин
Количество просмотров 51K
Всего голосов 27: ↑25 и ↓2 +23
Комментарии 18

Комментарии 18

olegchir тот момент когда один из главных разработчиков родом из России и в прошлом активно писал на хабр, но не додумался написать про TestContainers :D


Спасибо за перевод!
Надо бы мне мою https://medium.com/@bsideup/testing-your-docker-containers-with-testcontainers-and-groovy-3b9ef97ad1c2 тоже перевести.


P.S. ходят слухи что на Heisenbug 2017 Moscow так же будет доклад про TestContainers ;)

Кстати, видел этот коммит, по нему считал! Но догадался только вычесть годы :)

image
«Я пишу не только на Медиум и англоязычные блоги;
Ибо кто пишет только в англоязычные блоги — забыл лицо своего отца.
Я же пишу на Хабр.»

Ждем статьи, стрелок!

P.S. ходят слухи что на Heisenbug 2017 Moscow так же будет доклад про TestContainers ;)

говорят, что нет )))

ты просто не с теми говоришь ;)

:D
> Понравилась идея, есть сомнения?
да
> Будете ли вы пользоваться TestContainers?
нет

Из предыдущего и текущего опыта интеграционного и системного тестирование сервисов, для себя сделал вывод, что оркестрация докеров изнутри кода — идея ущербная по двум причинам.

1. Запускается только локально или на одной DOCKER_HOST ноде.
Идеальный сферический микросервис без зависимостей — будет ок.
Но реальные явишные сервисы, которые пришлось тестировать, жрут от полгига до 16 гиг памяти, имеют кучу зависимостей и на одну ноду просто не влазят. Тоже самое касается параллельного выполнения тестов. При попытке запустить дюжину selenium нод c chrome внутри — придется отдать гигов шесть, плюс собсвенно selenium grid — еще полтора — два гига, ну и собственно тестовым процессам памяти тоже бывает нужно по наблюдениям от половины до полутора гиг. Можно спорить о конкретных значениях и пытаться оптимизировать Xmx но на порядок величины — это не сильно влияет. Заурядная рабочая машина с 16 гигами памяти — не справится запустить этот тестовый сетап.

2. Второй контраргумент. Поптыка оркестрировать докеры из явишного кода — имхо, изобретание девопс велосипеда. Есть инструменты, которые делают лучше и больше.

Например
А. Вот этот плагин (были про него статьи на хабре даже) github.com/fabric8io/docker-maven-plugin — Тоже ограничен локальным хостом, но умеет не только запускать докеры для тестов и гасить после, но и собирать их, тегать, пушить в docker-registry на стадии mvn deploy, что удобно. Не подойдет ненавистникам XML конфигураций и мавена, однако проверен временем и работает удовлетворительно.

Б. kubernetes. Запросто жонглирует тяжелыми тестовыми сетапами, которые не поднимутся на локальной рабочей машине у разработчика, масштабирует компоненты по щелчку пальцев, про удобство конфигурации — и говорить нечего, это на два порядка лучше, чем конфигурить докеры в ява коде, к тому же любители YAML/JSON конфигов будут счастливы. Про тонны плюшек k8, которые идут впридачу к этому — тоже промолчу.
Так подожди, должен же разработчик на своем компьютере запустить сервис, с которым ты интегрируешься прямо сейчас и погонять немного тестов?

Ведь иначе придется ворочить полноценными кластерами, а это огромный оверхед сразу по всем фронтам. Особенно по времени реакции всевозможных админов.

Я как раз почти всю дорогу ворочил жирносервисами на джаве, и понимаю какая эта боль. Да, тридцать два гига рамы на локальном компьютере, да — i7, SSD, и по несколько минут на запуск. Но связываться с «полномасштабной» инфраструктурой — это еще больнее!
должен же разработчик на своем компьютере запустить сервис, с которым ты интегрируешься прямо сейчас и погонять немного тестов?

Конечно, он может. Те разработчики, которые хотят «немного погонять» в нашем случае предпочитают запускать spring boot у себя без докера на голом железе (им так привычнее и быстрее). Те разработчики, которые хотят локально выполнить интеграционный набор тестов а-ля Jenkins полностью — просто запускают mvn verify (который билдит и запускает все докеры с зависимостями локально) При этом в коде тестов — только логика тестов, вся конфигурация докеров — в настройках мавен докер плагина. И я настаиваю, что держать конфигурацию докеров снаружи тестового кода — лучше, чем засовывать её внутрь.

Да, тридцать два гига рамы на локальном компьютере, да — i7, SSD, и по несколько минут на запуск. Но связываться с «полномасштабной» инфраструктурой — это еще больнее!


«TestContainers — это Java-библиотека, которая поддерживает тесты JUnit и предоставляет легкие, временные экземпляры основных баз данных, веб-браузеров для Selenium или чего угодно еще, что можно запускать в Docker-контейнере».


Этот дисклеймер слегка сбивает с толку.
Выходит, что не «чего угодно ещё», а только того, что влезет на локальный компьютер.
В случае с selenium тестами — как правило речь идет о системном тестировании, где не обойдешься изолированным контекстом одного сервиса с базой данных, и где как раз и нужно поднимать эту самую полномасштабную инфраструктуру. Ну так вот kubernetes в этом случае спасает даже тех, у кого рабочий ноут с <32 Гб памяти. Опять же запустить kubernetes apply — как правило проще и быстрее, чем апгрейдить или покупать новые ноутбуки.
Понял. Может быть, это вопрос разных вкусов?

Тут есть отличное качество… отличное для извращенца типа меня. Человек может не знать ни о каких докерах, кубернетисах, итп. Все это магия. Все это инкапсулировано в несколько слоев абстракции. Нужна база данных? Просто создаешь ее в джава-коде, как любой другой класс, и вот тебе база данных. Это в точности то, что хотел сделать я сам — погрести Докер под плотным слоем абстракций, чтобы работа с ним осуществлялась аналогично класслоадерам в джаве или бинам в спринге, через прозрачный доступ по Java API и только через него.

Еще момент. Я всем сердцем люблю статику, статическую типизацию, code-time и compile-time проверки, комплияторы и IDE умнее разработчика. Поэтому и языки — Java, Scala, C++. Если UI — то TypeScript, ни в коем случае не JS. И так далее. Мечтаю перейти на Haskell, чтобы использовать его как пруфер чистоты фукнционального кода.

Вполне логично, что идея configuration as code, где код — это непосредственно код на Java, очень греет сердце. XML тоже хорош, пока это четкий и машинно-понимаемый XML. А вот Докер и командная страка — в этой парадигме, это динамическое непойми что. Сорри за жесткость данного утверждения.

Вторая часть истории — это функциональная чистота и формальная верификация. Когда ты запускаешь что-то вручную, например SpringBoot вручную из IDE, то это опять же непонятно насколько грязное решение. Тупо в Идее могут кэши не почиститься, и соберется ересь. Запуск в стерильном докере решает этот вопрос.

И заодним, можно не настраивать свой компьютер на запуск приложения вне IDE — не замусоривать его ненужными зависимостями типа десяти разных версий Ruby одновременно. Например, интегрируемся мы с GitLab — знаете сколько мусора притаскивает GitLab на твой компьютер? Потом с мыслом не отмыться, никогда. А как добиться репродуцируемости конфигурации твоего компьютера? А как менять их между разными версиями? («надо откатиться до предыдущей версии инфраструктуры, потому что в этой что-то глючит, но не понять — что»)

Все это — глобальная система представления о мире. Чистота, статика, верификация, совершенный контроль, умные тулзы позволяющие все это делать. Можно сделать из этого чеклист.

У кого-то другая система представлений.
Человек может не знать ни о каких докерах, кубернетисах, итп.

У кого-то другая система представлений.


Может кто-то просто не хочет знать ничего, кроме явы?

погрести Докер под плотным слоем абстракций, чтобы работа с ним осуществлялась аналогично класслоадерам в джаве или бинам в спринге, через прозрачный доступ по Java API и только через него


Вот это как раз оно. Грести докер под плотным слоем абстракций. Натянуть сову на глобус, чтобы было все через ява АПИ.
Представим некого сферического чудика, который вообще ничего кроме Java знать не хочет. Вообще. И что? Он теперь не человек?
желаю успехов в оркестрации докеров с помощью Java
жду статей про оркестрацию с помощью Scala и Haskel
Будете ли вы пользоваться TestContainers? Понравилась идея, есть сомнения?


В этом году мы довольно быстро внедрили TestContainers для проекта github.com/CourseOrchestra/celesta. Сергей про нас уже знает, общались на конференциях :-) Мы делаем систему, которая должна себя одинаково вести на разных типах СУБД. Соответственно, у нас есть набор тестов, который надо прогонять, по очереди присоединяясь к реальным SQLServer, Oracle и PostgreSQL (сама суть нашего проекта делает использование H2 для полной проверки невозможным). До TestContainers эти тесты требовали долгой ручной настройки среды (установка баз, прописывание конфигураций в бесконечных пропертях), и в полном объёме выполнялись (если выполнялись) на машине у единственного разработчика, где всё хозяйство было настроено. На CI выполнялся только H2. Ну и периодически у пользователей выплывали баги, которые мы могли бы поймать на имеющихся тестах, если бы они выполнялись.

После внедрения TestContainers требования к среде, где должна запускаться Maven-сборка проекта, сводятся к трём пунктам: JDK, Maven, Docker. Всё! Мы гоняем их всех на CI и горя не знаем.

Может быть, подойдёт не всем, но для нашего кейса TestContainers оказались тем, «что доктор прописал».
Спасибо! Ценный отзыв. Может быть, побольше таких отзывов, и люди перестанут пугаться.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий