Как я могу пропустить тесты в 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в разделpluginMaven-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.