Как я могу пропустить тесты в Maven install goal, запустив их в Maven test goal?

у меня есть многомодульный проект maven с интеграцией и модульными тестами в одной папке (src/test/java). Интеграционные тесты отмечены @Category(IntegrationTest.class). Я хочу закончить со следующей настройкой:

  1. если я запускаю mvn install, Я хочу, чтобы все тесты компилировались, но я не хочу их выполнять.
  2. если я запускаю mvn test, Я хочу, чтобы все тесты компилировались, но выполнялись только модульные тесты.
  3. если я запускаю 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 награды ...с чего бы мне вообще его запускать??

после нескольких часов гуглить и пробовать различные комбинации, я сомневаюсь, можно ли даже не запускать тесты в mvn install, в то же время запустить их в mvn test. Я надеюсь, что кто-то доказывает, что это не так. ;)

Я также готов примите решение, где mvn install будет выполнять только модульные тесты, но я не думаю, что это делает большой разницы.

6 ответов


похоже, вы не поняли понятие построить жизненного цикла в 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>

Итак, ваше первое требование:

  1. если я запускаю mvn install, Я хочу, чтобы все тесты компилировались, но я не хочу их выполнять.

может быть достигнуто путем использования следующий:

mvn -Pno-unit-test test
  1. если я запускаю mvn test, я хочу, чтобы все тесты компилировались, но выполнялись только модульные тесты.

это может быть просто достигнуто с помощью простого вызова:

mvn test

причина фаза интеграционных тестов не выполняется (см. Жизненный цикл сборки).

  1. если я запускаю 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), а не на скомпилированные имена (.класс.) Я бы не использовал аннотацию категории, просто используя соглашения об именах, делает pom проще и короче.


по словам отказоустойчивая документация плагина

mvn install -DskipITs

это то, что вы хотите.


что ОП заявил в своем вопросе:

если я запускаю mvn установить, я хочу, чтобы все тесты компилировались, но я не хочу казнить любого.
Если я побегу mvn тест, я хочу, чтобы все тесты компилировались, но выполнялись только модульные тесты.
Если я побегу интеграция mvn-тест, я хочу, чтобы скомпилировать и выполнить все тесты.

вполне допустимо и очень легко достичь.
редактировать: кроме первое условие, которое действует снова природа 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-плагин docs имеет раздел под названием " Пропуск по умолчанию."

к сожалению, шаги, описанные на этой странице, не работают так, как написано. Однако небольшое изменение этих шагов заставит его работать:

на на pom.xml добавить это:

<skipITs>true</skipITs>

добавить skipTests свойства plugin раздел maven-failsafe-плагин:

<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 так долго не любили.


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.