Как пропустить тесты в целях установки maven при запуске их в целях тестирования maven?
У меня есть мультимодульный проект maven с интеграционными и модульными тестами в той же папке (src/test/java). Тесты интеграции отмечены знаком @Category(IntegrationTest.class)
. Я хочу завершить следующую настройку:
- Если я запустил
mvn install
, я хочу, чтобы все тесты компилировались, но я не хочу их выполнять.
- Если я запустил
mvn test
, я хочу, чтобы все тесты компилировались, но выполнялись только модульные тесты.
- Если я запустил
mvn integration-test
, я хочу скомпилировать и выполнить все тесты.
Важным моментом является то, что я хочу, чтобы это было настроено в pom.xml
без каких-либо дополнительных аргументов командной строки.
В настоящее время я придумал следующую настройку в родительском pom.xml, где единственная проблема - №1, где выполняются все тесты:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${project.java.version}</source>
<target>${project.java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
<excludedGroups>cz.cuni.xrg.intlib.commons.IntegrationTest</excludedGroups>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.14.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
<configuration>
<groups>cz.cuni.xrg.intlib.commons.IntegrationTest</groups>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
Все дочерние модули имеют следующую конфигурацию плагина в своем pom.xml, который, как я полагаю, должен наследовать от родительского pom:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
</plugins>
</build>
Я попытался использовать <skipTests>true</skipTests>
, но он отключает выполнение теста для всех целей, что не то, что я хочу (нарушает # 2 и # 3). Также довольно странно, что mvn test
отличит параметр skipTests=true
... почему я хочу запустить его в первую очередь?
После нескольких часов работы с поиском и попытками разных комбинаций я не решаюсь, можно ли даже не запускать тесты в mvn install
, а в то же время запускать их в mvn test
. Надеюсь, кто-то докажет это неправильно.;)
Я также согласен принять решение, где mvn install
будет выполнять только модульные тесты, но я не думаю, что это имеет большое значение.
Ответы
Ответ 1
Похоже, вы не поняли концепцию жизненного цикла сборки в Maven. Если вы запускаете mvn install
все фазы жизненного цикла (включая саму фазу install
) выполняются до фазы установки. Это означает выполнение следующих этапов:
- утверждать
- инициализировать
- генерировать-источники
- Процесс-источники
- генерировать-ресурсы
- Процесс-ресурсы
- компилировать
- Процесс-классы
- генерировать-тест-источников
- Процесс-тест-источники
- генерировать-тест-ресурсы
- Процесс-тест-ресурсы
- тест-компиляция
- Процесс-тест-классы
- тестовое задание
- подготовить-пакет
- пакет
- Предварительная интеграция-тест
- Интеграция испытаний
- после интеграции тест
- проверить
- устанавливать
другими словами, включены этапы жизненного цикла test
а также integration-test
. Поэтому без какой-либо дополнительной информации невозможно изменить поведение по вашему желанию.
Это может быть достигнуто с помощью профиля в Maven:
<project>
[...]
<profiles>
<profile>
<id>no-unit-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
[...]
</project>
Итак, ваше первое требование:
- Если я запускаю
mvn install
, я хочу, чтобы все тесты компилировались, но я не хочу их выполнять.
может быть достигнуто с помощью следующего:
mvn -Pno-unit-test test
- Если я запускаю
mvn test
, я хочу, чтобы все тесты компилировались, но выполнялись только модульные тесты.
Это может быть просто достигнуто с помощью простого вызова:
mvn test
потому что фаза интеграционных тестов не запущена (см. жизненный цикл сборки).
- Если я запускаю
mvn integration-test
, я хочу скомпилировать и выполнить все тесты.
Это означает запуск по умолчанию, который включает в себя запуск фазы test
которая запустит модульные тесты (maven-surefire-plugin) и, кроме того, запуск интеграционного теста, который обрабатывается maven-failsafe-plugin. Но вы должны знать, что если вы хотите вызвать интеграционные тесты, вы должны использовать следующую команду:
mvn verify
вместо этого, потому что вы пропустили фазу post-integration-test
в вашем предыдущем вызове.
Помимо вышесказанного, вы должны следовать соглашениям об именах для модульных и интеграционных тестов, где модульные тесты должны называться следующим образом:
<includes>
<include>**/*Test*.java</include>
<include>**/*Test.java</include>
<include>**/*TestCase.java</include>
</includes>
и интеграционные тесты должны быть названы так:
<includes>
<include>**/IT*.java</include>
<include>**/*IT.java</include>
<include>**/*ITCase.java</include>
</includes>
Я надеюсь, что вы настроили maven-failsafe-plugin, как показано ниже, который необходим для привязки maven-failsafe-plugin к правильным фазам жизненного цикла:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.15</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
как вы правильно сделали, но вы должны знать, что теги include
работают с исходным кодом (.java), а не скомпилированными именами (.class). Я бы не использовал аннотацию Category, просто использование соглашений об именах делает pom проще и короче.
Ответ 2
Согласно документации Failsafe Plugin
mvn install -DskipITs
это то, что вы хотите.
Ответ 3
Что ОП задал в своем вопросе:
Если я запустил mvn install, я хочу, чтобы все тесты компилировались, но я не хочу выполнить любой.
Если я запустил mvn test, я хочу, чтобы все тесты компилировались, но выполнялись только модульные тесты.
Если я запустил mvn integration-test, я хочу скомпилировать и выполнить все тесты.
совершенно справедливо и чрезвычайно легко достичь.
EDIT: кроме первого условия, которое действует снова в природе. Лучше всего здесь просто сделать mvn install -DskipTests
Все, что вам нужно, это следующий фрагмент в pom.xml
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>integration-tests</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
и придерживаться условных обозначений maven для тестов unit и интеграции (как уже говорилось в @khmarbaise). Поэтому обычно называйте интеграционные тесты с суффиксом IT
(например, MyIntegrationTestIT.java
), и пусть maven-failsafe
выполняет свою работу.
Таким образом, вам даже не нужны категории JUnit (хотя иногда они могут быть весьма полезными).
Что это:)
-
mvn test
выполняет только модульные тесты
-
mvn integration-test
выполняет все тесты
-
mvn failsafe:integration-test
выполняется только интеграционные тесты
-
mvn clean verify
, когда вы хотите быть уверенным, что весь проект просто работает.
Некоторые личные советы
Сохранение интеграционных тестов отдельно от модульных тестов позволяет легко запускать внутри вашей IDE все тесты в некоторых пакетах. Обычно для этого используется дополнительный каталог с именем test-integration
(или integrationtest
).
Это также легко достичь с помощью maven:
<plugin>
<!-- adding second test source directory (just for integration tests) -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>add-integration-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test-integration/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
И затем переместите тесты интеграции в этот каталог. Он должен выглядеть так:
src
main
test
test-integration
Для тестов интеграции обычно требуется больше памяти:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
...
<configuration>
<argLine>-Xmx512m -XX:MaxPermSize=256m</argLine>
</configuration>
</plugin>
Ответ 4
В этом посте объясняется, как пропустить интеграционные тесты, независимо от того, какой плагин вы используете для этих тестов.
По сути, вы определяете профиль и помещаете в него все свои xml-коды, связанные с интеграционными тестами. Чем вы активируете его, когда свойство -DskipIntegrationTests
отсутствует.
Вы можете сделать то же самое для модульных тестов: написать профиль и активировать его, если отсутствует -DskipUnitTests
.
Затем вы можете сделать:
mvn install -DskipIntegrationTests -DskipUnitTests # (runs install without any tests)
mvn test # (runs unit tests)
mvn post-integration-test # (runs all tests)
Ответ 5
В maven-failafe-plugin docs есть раздел под названием "Пропуск по умолчанию".
К сожалению, шаги, описанные на странице, не работают так, как написано. Однако небольшое изменение этих шагов заставит его работать:
В разделе properties
pom.xml
добавьте следующее:
<skipITs>true</skipITs>
Затем добавьте свойство skipTests
в раздел plugin
maven-failafe-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skipTests>${skipITs}</skipTests>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
Итак, теперь mvn install
по умолчанию будет выполнять модульные тесты, но не интеграционные тесты.
Но mvn install -DskipITs=false
будет выполнять как модульные тесты, так и интеграционные тесты.
Сноска: Плохая документация сыграла большую роль в том, почему Maven так долго не нравился.
Ответ 6
mvn test-compile
выполняет именно то, что вы ищете. Вы можете просто заменить mvn install
на mvn test-compile
, и все готово. Нет необходимости настраивать файл pom или что-то еще. Следующий связанный вопрос похож на # 1:
Maven - Как скомпилировать тесты без их запуска?
mvn test-compile
должен быть принят как лучший ответ, поскольку Maven поддерживает именно то, что вы хотите сделать изначально и без магии. В итоге вы получите следующее:
If I run mvn test-compile, I want all tests to compile, but I do not want to execute any.
If I run mvn test, I want all tests to compile, but execute only unit tests.
If I run mvn integration-test, I want to compile and execute all tests.
Ответ 7
Не указывайте этапы выполнения в конфигурации отказоустойчивого плагина. Например
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
</plugins>
Теперь вам необходимо вызвать mvn failsafe: интеграционный тест для запуска интеграционных тестов; они будут пропущены в других целях mvn.