Всем привет!
Пару слов про отладку тестов, на примере 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
Пару слов про отладку тестов, на примере 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
Stack Overflow
How to debug integration test in IntelliJ?
I have created run configuration in Maven Projects for
mvn -Dit.test=PredictionWorkflowTest verify
which looks like here
and then set breakpoint inside PredictionWorkflowTest. Unfortunately, whe...
mvn -Dit.test=PredictionWorkflowTest verify
which looks like here
and then set breakpoint inside PredictionWorkflowTest. Unfortunately, whe...
Всем привет!
Нашел хорошую статью о том, как совместить тестирование Spring контроллеров и один из самых известных фреймворков для тестирования REST - Rest Assured. https://www.baeldung.com/spring-mock-mvc-rest-assured
Кстати, в начале статьи есть ссылка на пример использования чистого Spring MVC Test, если кто его не использовал - можете сравнить синтаксис.
Еще статья хороша тем, что четко разделяет модульные и интеграционные тесты. И я бы разделил точно также) Я иногда задаю вопрос о видах тестов на интервью, ответ мне не всегда нравится. Для ленивых, вкратце - интеграционным тест можно считать, если появляется сеть - открывается порт, вызывается другой процесс, внешнее хранилище, пусть даже и в embedded варианте. Хотя справедливости ради - вопрос холиварный, из-за того, что много пограничных случаев.
#unittests #spring #rest #integration_tests #interview_question
Нашел хорошую статью о том, как совместить тестирование Spring контроллеров и один из самых известных фреймворков для тестирования REST - Rest Assured. https://www.baeldung.com/spring-mock-mvc-rest-assured
Кстати, в начале статьи есть ссылка на пример использования чистого Spring MVC Test, если кто его не использовал - можете сравнить синтаксис.
Еще статья хороша тем, что четко разделяет модульные и интеграционные тесты. И я бы разделил точно также) Я иногда задаю вопрос о видах тестов на интервью, ответ мне не всегда нравится. Для ленивых, вкратце - интеграционным тест можно считать, если появляется сеть - открывается порт, вызывается другой процесс, внешнее хранилище, пусть даже и в embedded варианте. Хотя справедливости ради - вопрос холиварный, из-за того, что много пограничных случаев.
#unittests #spring #rest #integration_tests #interview_question
Baeldung
REST-assured Support for Spring MockMvc | Baeldung
Learn how to test Spring REST controllers using the RestAssuredMockMvc API from REST-assured.
Всем привет!
Продолжение про тесты, на этот раз интеграционные.
Доминирующий протокол для интеграции сейчас - 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
Продолжение про тесты, на этот раз интеграционные.
Доминирующий протокол для интеграции сейчас - 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
Baeldung
Integration Testing Spring WebClient Using WireMock | Baeldung
Learn how to utilize WireMock API to stub HTTP-based client requests when using WebClient.