Как я могу пропустить тесты в maven install goal, запустив их в maven test goal?
У меня есть многомодульный проект 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
будет выполняться только модульные тесты, но я не думаю, что это имеет большое значение.6 ответов:
Похоже, вы не поняли концепциюжизненного цикла сборки в Maven. Если вы запускаете
mvn install
все фазы жизненного цикла (включая саму фазуinstall
), запускаются до фазы установки. Это означает выполнение следующих действий фазы:
- проверить
- инициализировать
- генерация-источники
- процесс-источники
- generate-resources
- процесс-ресурсы
- компиляция
- классы процессов
- generate-test-sources
- процесс-тест-источники
- generate-test-resources
- процесс-тест-ресурсы
- test-compile
- процесс-тест-классы
- тест
- подготовка пакета
- пакет
- предварительный интеграционный тест
- интеграционный тест
- постинтеграционный тест
- проверить
- установить
Который другими словами, включаются фазы жизненного цикла
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-плагину. Но вы должны знать, что если вы хотите вызвать интеграционные тесты, вы должны использовать следующую команду: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), а не на скомпилированных именах (.класс). Я бы не стал использовать аннотацию категории, просто использование соглашений об именовании делает pom проще и короче.
В соответствии с отказоустойчивой документацией плагина
mvn install -DskipITs
Это то, что вы хотите.
Что заявил ОП в своем вопросе:
Если я запускаю mvn install , я хочу, чтобы все тесты компилировались, но я не хочу казнить любого.
Если я запускаю mvn test , я хочу, чтобы все тесты компилировались, но выполнялись только модульные тесты.
Если я запускаю mvn integration-test , я хочу скомпилировать и выполнить все тесты.Является совершенно действительным и чрезвычайно легко достижимым.
правка: кроме первого условия, которое действует против природы maven. Лучший способ здесь был бы просто сделать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 соглашений об именовании для модульных и интеграционных тестов (как уже говорилось @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>
Этот пост объясняет, как пропустить интеграционные тесты, независимо от того, какой плагин вы используете для этих тестов.
В основном, то, что вы делаете,-это определяете профиль и помещаете весь свой xml-код, связанный с интеграционными тестами, в этот профиль. Чем вы активируете его, когда свойство
-DskipIntegrationTests
отсутствует.Вы можете сделать то же самое для модульных тестов: написать профиль и активировать его, когда
-DskipUnitTests
отсутствует.Тогда вы могли бы сделать:
mvn install -DskipIntegrationTests -DskipUnitTests # (runs install without any tests) mvn test # (runs unit tests) mvn post-integration-test # (runs all tests)
Maven-failsafe-plugindocs имеет раздел под названием "Пропуск по умолчанию."
К сожалению, шаги, описанные на странице, не работают так, как написано. Однако небольшое изменение этих шагов заставит его работать:В разделе
properties
разделаpom.xml
добавьте следующее:
<skipITs>true</skipITs>
Затем добавьте СВОЙСТВО
skipTests
в разделplugin
Maven-failsafe-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
по умолчанию будет выполнять модульные тесты, но не интеграционные тесты.Но an
Примечание: плохая документация сыграла большую роль в том, почему Мэйвена так долго не любили.mvn install -DskipITs=false
будет выполнять как модульные тесты, так и интеграционные тесты.
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.