(java || kotlin) && devOps
369 subscribers
6 photos
1 video
6 files
306 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Всем привет!

Пару слов про отладку тестов, на примере Maven проекта и IDEA.

Если речь про модульные тесты - там проблем нет, ставим breakpoint и запускаем нужный тест в IDEA.

Проблемы есть с интеграционными тестами. Т.к.
1) тесты и код, который тестируем, запускаются в разных процессах
2) обычно интеграционные тесты запускаются с помощью Maven (Gradle), т.к. нужно поднять окружение, и проще и правильнее эти настройки один раз сделать в Maven и забыть.

Какие у нас варианты с отладкой?

1) вариант, описанный тут https://stackoverflow.com/questions/49390110/how-to-debug-integration-test-in-intellij
Если вкратце - запускаем тесты с помощью Maven в специальном отладочном режиме плагина failsafe (или surefire), потом подключаемся к процессу из IDEA в режиме удаленной отладки. Отладка называется удаленной, т.к. нужно подключаться к другому процессу. В данном случае на localhost.

2) запускаем наш сервис в "DEV режиме" через Maven. Также, как это делается для отладки кода и проверки функционала локально вручную. Обычно под это дело в проекте есть отдельный профиль Maven. После этого запускаем нужный интеграционный тест в Debug режиме из IDEA, из окна с кодом теста. Как минимум, интеграционные тесты Cucumber и Spring Boot IDEA поддерживает.

3) а что, если нужно поставить точку прерывания в коде сервиса, а не тестов? Тогда настаиваем в IDEA Run configuration для нашего контейнера сервлетов \ сервера приложений. Запускаем ее в DEBUG режиме, после чего запускаем тесты также, как и в предыдущем варианте.

Варианты 2 и 3 мне нравятся больше, т.к. не нужно использовать консоль - все делается средствами IDEA.

#debug #java #tests #integration-tests
Всем привет!

Нашел хорошую статью о том, как совместить тестирование Spring контроллеров и один из самых известных фреймворков для тестирования REST - Rest Assured. https://www.baeldung.com/spring-mock-mvc-rest-assured

Кстати, в начале статьи есть ссылка на пример использования чистого Spring MVC Test, если кто его не использовал - можете сравнить синтаксис.

Еще статья хороша тем, что четко разделяет модульные и интеграционные тесты. И я бы разделил точно также) Я иногда задаю вопрос о видах тестов на интервью, ответ мне не всегда нравится. Для ленивых, вкратце - интеграционным тест можно считать, если появляется сеть - открывается порт, вызывается другой процесс, внешнее хранилище, пусть даже и в embedded варианте. Хотя справедливости ради - вопрос холиварный, из-за того, что много пограничных случаев.

#unittests #spring #rest #integration_tests #interview_question
Всем привет!

Продолжение про тесты, на этот раз интеграционные.
Доминирующий протокол для интеграции сейчас - http(s). REST, GraphQL, разные кастомные реализации. Если мы получаем данные по http - значит где-то есть http client. Он куда-то стучится. Как можно протестировать эту часть интеграционной цепочки?
На первый взгляд, самый простой вариант - развернуть в TestContainers реальный экземпляр сервиса поставщика. Но у нас же микросервисы, а значит он, возможно, вызывает ещё кого-то. И т.д. Даже если не вызывает - ходит в БД.
Поэтому для теста, да и для отладки, нужна заглушка. Кстати, в большинстве случаев это может быть одна и та же заглушка.
Заглушка может быть standalone и встроенная. Я за встроенную, т.к. удобно держать в одном репозитории с кодом и сам код, и все необходимые настройки для его отладки и работы. Кроме стендозависмых конечно.
Что нас нужно от заглушки:
1) возможность старта на произвольном порту и передачи этого порта в код (сервер всегда localhost). Захардкодить порт можно, но тесты запускаются на CI конвейере, в т.ч. на используемом совместно сервере. И вообще не должны зависеть от среды запуска.
2) удобная возможность задавать разные ответы для разных path, например, method chaining
3) учёт параметров в URL
4) возможность задать http код ответа
5) возможность задать http заголовки ответа
6) возможность эмулировать таймаут
Ну и в идеале простая инициализация в тесте, например, с помощью аннотации.

И вот наконец кандидаты.
1) Wiremock. Главные плюсы - большое число возможностей, накопленных за время существования, и возможность работы как во встроенном режиме, так и standalone. Примеры фишек Wiremock - сценарный режим, когда можно задать ответ в зависимости от предыдущего запроса. Встроенный генератор случайных данных в полях ответа. Возможность использовать данные запроса в ответе (templating). Статья как подружить Wiremock с тестами https://www.baeldung.com/spring-webclient-wiremock-integration-testing
2) @RestClientTest - это «магическая» аннотация Spring Boot, автоматически связывающая добавленный в класс теста RestTemplate с сервером заглушки. Т.е. настройку порта делать не нужно. Вот статья по использованию https://www.baeldung.com/restclienttest-in-spring-boot
Если используете Spring и RestTemplate или его наследника RestClient - наверное оптимальный вариант. Для WebClient - асинхронщины и реактивщины - не годится, соответствующий тикет был отклонен командой Spring https://github.com/spring-projects/spring-boot/issues/8404
3) А рекомендует Spring для WebClient использовать MockWebServer. Вот статья https://howtodoinjava.com/java/library/mockwebserver-junit-webclient/
Из интересных фишек я заметил возможность получения информации о последнем запросе, пришедшем на сервер. И простейший сценарный режим, когда можно настроить очередь ответов для ряда последовательных запросов. Настраивать сложнее, чем предыдущие два варианта.

Итого: рекомендую @RestClientTest для синхронного Spring и Wiremock для остального.

#integration_tests #rare_test libs