1. Обзор
В типичной разработке через тестирование мы стремимся написать много низкоуровневых модульных тестов, которые быстро запускаются и настраиваются изолированно. Кроме того, есть также несколько высокоуровневых интеграционных тестов, которые зависят от внешних систем, например, настройка сервера или баз данных. Неудивительно, что они, как правило, требуют как ресурсов, так и времени.
Следовательно, эти тесты в основном требуют некоторой настройки перед интеграцией и очистки после интеграции для корректного завершения. Поэтому желательно различать два типа тестов и иметь возможность запускать их отдельно в процессе сборки.
В этом руководстве мы сравним подключаемые модули Surefire и Failsafe, наиболее часто используемые для запуска различных типов тестов в типичной сборке Apache Maven .
2. Плагин Surefire
Плагин Surefire принадлежит к набору основных плагинов Maven и запускает модульные тесты приложения.
POM проекта включает этот плагин по умолчанию, но мы также можем настроить его явно:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
....
</plugin>
</plugins>
</pluginManagement>
</build>
Плагин привязывается к тестовой
фазе жизненного цикла по умолчанию . Поэтому выполним его командой:
mvn clean test
Это запускает все модульные тесты в нашем проекте. Поскольку подключаемый модуль Surefire связывается с фазой тестирования
, в случае каких-либо сбоев теста сборка завершается с ошибкой, и в процессе сборки дальнейшие фазы не выполняются .
Кроме того, мы можем изменить конфигурацию плагина для запуска интеграционных тестов, а также модульных тестов. Однако это может быть нежелательным поведением для интеграционных тестов, которые могут потребовать некоторой предварительной настройки среды, а также некоторой очистки после выполнения теста.
Maven предоставляет другой плагин именно для этой цели.
3. Отказоустойчивый плагин
Плагин Failsafe предназначен для запуска интеграционных тестов в проекте.
3.1. Конфигурация
Во-первых, давайте настроим это в проекте POM:
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M5</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
....
</execution>
</executions>
</plugin>
Здесь цели плагина связаны с интеграционным тестом
и проверяют
этапы цикла сборки для выполнения интеграционных тестов.
Теперь давайте выполним фазу проверки
из командной строки:
mvn clean verify
Это запускает все интеграционные тесты, но если какие-либо тесты терпят неудачу на этапе интеграционного тестирования
, плагин не сразу завершает сборку .
Вместо этого Maven по-прежнему выполняет фазу тестирования после интеграции
. Поэтому мы по-прежнему можем выполнять любую очистку и демонтаж среды в рамках фазы постинтеграционного тестирования
. На последующем этапе проверки
процесса сборки сообщается обо всех неудачных тестах.
3.2. Пример
В нашем примере мы настроим сервер Jetty так, чтобы он запускался до запуска интеграционных тестов и останавливался после выполнения теста.
Во-первых, давайте добавим плагин Jetty в наш POM:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.11.v20180605</version>
....
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
Здесь мы добавили конфигурацию для запуска и остановки сервера Jetty на этапах до и после тестирования
интеграции
соответственно.
Теперь давайте еще раз выполним наши интеграционные тесты и посмотрим на вывод консоли:
....
[INFO] <<< jetty-maven-plugin:9.4.11.v20180605:start (start-jetty)
< validate @ maven-integration-test <<<
[INFO] --- jetty-maven-plugin:9.4.11.v20180605:start (start-jetty)
@ maven-integration-test ---
[INFO] Started ServerConnector@4b9dc62f{HTTP/1.1,[http/1.1]}{0.0.0.0:8999}
[INFO] Started @6794ms
[INFO] Started Jetty Server
[INFO]
[INFO] --- maven-failsafe-plugin:3.0.0-M5:integration-test (default)
@ maven-integration-test ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.foreach.maven.it.FailsafeBuildPhaseIntegrationTest
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.024 s
<<< FAILURE! - in com.foreach.maven.it.FailsafeBuildPhaseIntegrationTest
[ERROR] com.foreach.maven.it.FailsafeBuildPhaseIntegrationTest.whenTestExecutes_thenPreAndPostIntegrationBuildPhasesAreExecuted
Time elapsed: 0.012 s <<< FAILURE!
org.opentest4j.AssertionFailedError: expected: <true> but was: <false>
at com.foreach.maven.it.FailsafeBuildPhaseIntegrationTest
.whenTestExecutes_thenPreAndPostIntegrationBuildPhasesAreExecuted(FailsafeBuildPhaseIntegrationTest.java:11)
[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR] FailsafeBuildPhaseIntegrationTest.whenTestExecutes_thenPreAndPostIntegrationBuildPhasesAreExecuted:11
expected: <true> but was: <false>
[INFO]
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
[INFO]
[INFO] --- jetty-maven-plugin:9.4.11.v20180605:stop (stop-jetty)
@ maven-integration-test ---
[INFO]
[INFO] --- maven-failsafe-plugin:3.0.0-M5:verify (default)
@ maven-integration-test ---
[INFO] Stopped ServerConnector@4b9dc62f{HTTP/1.1,[http/1.1]}{0.0.0.0:8999}
[INFO] node0 Stopped scavenging
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
....
Здесь, согласно нашей конфигурации, сервер Jetty запускается до выполнения интеграционного теста. Для демонстрации у нас есть неудачный интеграционный тест, но это не приводит к немедленному сбою сборки. Фаза тестирования после интеграции
выполняется после выполнения теста, и сервер останавливается до сбоя сборки.
Напротив, если бы мы использовали подключаемый модуль Surefire для запуска этих интеграционных тестов, сборка остановилась бы на этапе интеграционного тестирования
без выполнения какой-либо необходимой очистки .
Дополнительным преимуществом использования разных плагинов для разных типов тестов является разделение между различными конфигурациями. Это улучшает ремонтопригодность сборки проекта.
4. Вывод
В этой статье мы сравнили плагины Surefire и Failsafe для разделения и запуска разных типов тестов. Мы также рассмотрели пример и увидели, как Failsafe Plugin предоставляет дополнительные функции для запуска тестов, требующих дополнительной настройки и очистки.
Как всегда, код доступен на GitHub .