Как мне запустить тесты интеграции Maven


170

У меня есть многомодульный проект maven2, и в каждом из моих дочерних модулей у меня есть тесты JUnit, которые названы Test.javaи Integration.javaдля модульных тестов и интеграционных тестов соответственно. Когда я выполню:

mvn test

Все тесты JUnit *Test.javaв дочерних модулях выполняются. Когда я выполню

mvn test -Dtest=**/*Integration

ни один из Integration.javaтестов не выполняется в дочерних модулях.

Мне кажется, что это одна и та же команда, но та, которая с -Dtest = / * Integration ** не работает, отображает 0 тестов, выполняемых на родительском уровне, которых нет.


4
Ответ Kief должен быть принят, так как он является текущим стандартом для определения интеграционных тестов в Maven.
heenenee

Ответы:


110

Вы можете настроить Maven's Surefire для отдельного запуска модульных и интеграционных тестов. На стандартном этапе модульного тестирования вы запускаете все, что не соответствует шаблону, соответствует интеграционному тесту. Затем вы создаете второй этап тестирования, который запускает только интеграционные тесты.

Вот пример:

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <configuration>
        <excludes>
          <exclude>**/*IntegrationTest.java</exclude>
        </excludes>
      </configuration>
      <executions>
        <execution>
          <id>integration-test</id>
          <goals>
            <goal>test</goal>
          </goals>
          <phase>integration-test</phase>
          <configuration>
            <excludes>
              <exclude>none</exclude>
            </excludes>
            <includes>
              <include>**/*IntegrationTest.java</include>
            </includes>
          </configuration>
        </execution>
      </executions>
    </plugin>

1
Я настроил это, как вы сказали, и при запуске будут запускаться только файлы * Test, а не * Integration.java: mvn install Мне нужно запустить мой * Test.java по умолчанию, но для моей ночной сборки мне нужно запустить оба * Test .java и * Integration.java. Я должен выполнить mvn install, затем cd для каждого дочернего каталога и выполнить mvn -Dtest = ** / * Интеграционный тест
Питер Делани,

66
Для тестирования интеграции следует использовать плагин Fail-safe, а не плагин sure-fire. Это не приведет к провалу сборки до тех пор , после того, как фаза после интеграции завершена; позволяя разбирать тестовые ресурсы (например, веб-сервер) до сбоя сборки. Следовательно, отказоустойчивый.
Джон Гордон

для меня, как часть фазы предварительной интеграции, запускается сервер Jetty. Последняя строка журнала: [INFO] Запущен Jetty Server. После этого ничего не происходит. Это застревает. Отказоустойчивый плагин maven surefire не выполняет тесты и сервер Jetty не останавливается. Есть идеи, что случилось? Я использую ту же конфигурацию, что и вы.
Тарун Кумар

6
Этот ответ очень устарел и должен быть обновлен или удален.
Зак Томпсон


250

Сборки Жизненный цикл Maven теперь включает в себя этап «Интеграция-тест» для выполнения тестов интеграции, которые работают отдельно от единичных испытаний , запущенным в фазе «тест». Он запускается после «package», поэтому, если вы запустите «mvn verify», «mvn install» или «mvn deploy», интеграционные тесты будут выполняться по пути.

По умолчанию интеграции тест проходит тестовые классы с именами **/IT*.java, **/*IT.javaи **/*ITCase.java, но это может быть настроено.

Для получения дополнительной информации о том , как подключить это все вверх, см Отказоустойчивого плагина , на Failsafe странице использования (не правильно связаны с предыдущей страницы , когда я пишу это), а также проверить этот блог Sonatype .


1
@WillV Правильно. Кладбище Кодехаус. А maven-failsafe-plugin теперь в Apache. Сожалею. :)
Джин Квон

38
По умолчанию mvn integration-testтакже запускаются модульные тесты (с использованием surefire), но mvn failsafe:integration-testвыполняются только отказоустойчивые интеграционные тесты.
Shadow Man

22
Невероятно, но в документации по плагину Failsafe, странице использования и FAQ не упоминается, что он запускает тестовые классы с именами * / IT .java, ** / * IT.java и ** / * ITCase.java ...
Henno Vermeulen

1
Если он запускается после packageфазы, это значит, что я должен поместить весь свой исходный код Java в Java src/main/javaвместо src/test/javaправильного?
Брюс Сан

5
@HennoVermeulen Я также не знал, как назвать тесты. Это описано во включениях и исключениях тестов . Хорошо, что настройки по умолчанию могут быть отменены, но было бы хорошо, если бы они упоминали настройки по умолчанию ранее.
Джошуа Тейлор

63

Я сделал именно то, что вы хотите сделать, и это прекрасно работает. Модульные тесты «* Tests» всегда выполняются, а «* IntegrationTests» запускаются только тогда, когда вы выполняете проверку mvn или установку mvn. Вот это фрагмент из моего ПОМа. serg10 почти правильно понял ... но не совсем.

  <plugin>
    <!-- Separates the unit tests from the integration tests. -->
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
       <!-- Skip the default running of this plug-in (or everything is run twice...see below) -->
       <skip>true</skip>
       <!-- Show 100% of the lines from the stack trace (doesn't work) -->
       <trimStackTrace>false</trimStackTrace>
    </configuration>
    <executions>
       <execution>
          <id>unit-tests</id>
          <phase>test</phase>
          <goals>
             <goal>test</goal>
          </goals>
          <configuration>
                <!-- Never skip running the tests when the test phase is invoked -->
                <skip>false</skip>
             <includes>
                   <!-- Include unit tests within integration-test phase. -->
                <include>**/*Tests.java</include>
             </includes>
             <excludes>
               <!-- Exclude integration tests within (unit) test phase. -->
                <exclude>**/*IntegrationTests.java</exclude>
            </excludes>
          </configuration>
       </execution>
       <execution>
          <id>integration-tests</id>
          <phase>integration-test</phase>
          <goals>
             <goal>test</goal>
          </goals>
          <configuration>
            <!-- Never skip running the tests when the integration-test phase is invoked -->
             <skip>false</skip>
             <includes>
               <!-- Include integration tests within integration-test phase. -->
               <include>**/*IntegrationTests.java</include>
             </includes>
          </configuration>
       </execution>
    </executions>
  </plugin>

Удачи!


Именно то, что я пытался сделать, но мои интеграционные тесты продолжали выполняться во время фазы тестирования mvn, так как я НЕ ПРОПУСКАЛ ПО УМОЛЧАНИЮ. Я думал, что настройка выполнения теста переопределит его. Как вы объяснили, он просто добавляет новое выполнение (таким образом, все будет выполняться дважды). Так что для меня скип пропал кусок. +1 Поскольку эта конфигурация отвечает на вопрос на 100%
Нильс Шмидт

2
Тогда не стесняйтесь установить флажок для этого ответа, являющегося ответом!
HDave

для меня, как часть фазы предварительной интеграции, запускается сервер Jetty. Последняя строка журнала: [INFO] Запущен Jetty Server. После этого ничего не происходит. Это застревает. Отказоустойчивый плагин maven surefire не выполняет тесты и сервер Jetty не останавливается. Есть идеи, что случилось? Я использую ту же конфигурацию, что и вы.
Тарун Кумар

@Tarun - задайте новый вопрос о своей проблеме
HDave

2
Это должен быть принятый ответ. Соответствующая цель Maven: clean compile integration-test -Dmaven.test.failure.ignore=false
Нил Лима

31

Вы можете очень легко разделить их, используя категории JUnit и Maven.
Это очень и очень кратко показано ниже при тестировании модуля разделения и интеграции.

Определить интерфейс маркера

Первым шагом в группировке теста с использованием категорий является создание интерфейса маркера.
Этот интерфейс будет использоваться для пометки всех тестов, которые вы хотите запустить, как интеграционных тестов.

public interface IntegrationTest {}

Отметьте свои тестовые занятия

Добавьте аннотацию категории в начало вашего тестового класса. Требуется имя вашего нового интерфейса.

import org.junit.experimental.categories.Category;

@Category(IntegrationTest.class)
public class ExampleIntegrationTest{

    @Test
    public void longRunningServiceTest() throws Exception {
    }

}

Настройка Maven модульных тестов

Прелесть этого решения в том, что ничего не изменится с точки зрения модульного тестирования.
Мы просто добавляем некоторую конфигурацию в плагин maven surefire, чтобы он игнорировал любые интеграционные тесты.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.11</version>
    <configuration>
        <includes>
            <include>**/*.class</include>
        </includes>
        <excludedGroups>
            com.test.annotation.type.IntegrationTest
        </excludedGroups>
    </configuration>
</plugin>

Когда вы это сделаете mvn clean test, будут выполняться только ваши немаркированные юнит-тесты.

Настроить интеграционные тесты Maven

Опять же, конфигурация для этого очень проста.
Мы используем стандартный отказоустойчивый плагин и настраиваем его для запуска только интеграционных тестов.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <includes>
            <include>**/*.class</include>
        </includes>
        <groups>
            com.test.annotation.type.IntegrationTest
        </groups>
    </configuration>
</plugin>

Конфигурация использует стандартную цель выполнения для запуска отказоустойчивого плагина во время фазы тестирования интеграции сборки.

Теперь вы можете сделать mvn clean install.
На этот раз, а также при выполнении модульных тестов интеграционные тесты выполняются на этапе интеграционных тестов.


Я думал, что у Юнита больше нет секретов для меня. Хорошее место!
Гертас

4
Это работает, только если интерфейс маркера уже существует в Maven. Он не работает, если ваш маркерный интерфейс существует в другом модуле той же многомодульной сборки.
EngineerBetter_DJ

@EngineerBetter_DJ что ты имеешь в виду под этим? Вы не можете сделать это, если у вас есть многопроектная конфигурация maven?
Matthieusb

16

Вы должны попробовать использовать maven failsafe плагин . Вы можете сказать, чтобы включить определенный набор тестов.


1
+1 Это то, что я использую. Хорошо работает и позволяет выполнять предварительную / последующую настройку, например запуск и выключение локального контейнера сервлета.
mdma

maven-failsafe-pluginотправился на кладбище плагинов
Джин Квон

9
Страница кладбища просто говорит, что failsafeплагин был перемещен в maven-failsafe-plugin. Похоже, что maven-failsafe-pluginон все еще активен (документы были в последний раз отправлены в марте 2014 года).
Джеймс Кингсбери

13

По умолчанию Maven запускает только те тесты, в которых Test находится где-то в имени класса.

Переименуйте в IntegrationTest, и это, вероятно, будет работать.

В качестве альтернативы вы можете изменить конфигурацию Maven для включения этого файла, но, вероятно, проще и лучше просто назвать ваши тесты SomethingTest.

Из включений и исключений тестов :

По умолчанию плагин Surefire автоматически включает все тестовые классы со следующими шаблонами подстановочных знаков:

  • \*\*/Test\*.java - включает в себя все его подкаталоги и все имена файлов Java, которые начинаются с «Test».
  • \*\*/\*Test.java - включает в себя все его подкаталоги и все имена файлов Java, которые заканчиваются на «Test».
  • \*\*/\*TestCase.java - включает все его подкаталоги и все имена файлов Java, которые заканчиваются на «TestCase».

Если тестовые классы не соответствуют соглашению об именах, настройте плагин Surefire и укажите тесты, которые вы хотите включить.


Привет и спасибо. У меня есть два вида обычных тестов POJO Junit под названием SomethingTest.java, которые запускаются. У меня также есть интеграционные тесты под названием SomethingIntegration.java, которые не запускаются. SomethingTest.java запускается с помощью mvn test или mvn install. Вторые тесты не увольняют. mvn test -Dtest = ** / * Интеграция
Питер Делани

... и "Maven запускает только тесты, у которых Test где-то в имени класса", вы имеете в виду "плагин Maven surefire только запускает тесты, у которых Test где-то в имени класса".
Джошуа Дэвис,

1
Это не «где-то в имени класса», это «имя класса заканчивается на Test», например, MyTest работает, но MyTests нет
Джулиан

10

Еще один способ запуска интеграционных тестов с Maven - использовать функцию профиля:

...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <includes>
                    <include>**/*Test.java</include>
                </includes>
                <excludes>
                    <exclude>**/*IntegrationTest.java</exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

<profiles>
    <profile>
        <id>integration-tests</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <includes>
                            <include>**/*IntegrationTest.java</include>
                        </includes>
                        <excludes>
                            <exclude>**/*StagingIntegrationTest.java</exclude>
                        </excludes>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
...

Запуск mvn clean install запустит сборку по умолчанию. Как указано выше, интеграционные тесты будут игнорироваться. Запуск mvn clean install -P интеграционные тесты будет включать интеграционные тесты (я также игнорирую свои промежуточные интеграционные тесты). Кроме того, у меня есть CI-сервер, который каждую ночь выполняет мои интеграционные тесты, и для этого я запускаю команду «mvn test -P интеграционные тесты» .


1
Почему бы вам не использовать этап тестирования интеграции? Профили могут затем использоваться для таких вещей, как интеграционное тестирование на различных серверах приложений и т. Д., Как это делает Arquillian. Я не эксперт Maven, но я думаю, что эксперты могли бы сказать, что это не очень Maven-y.
Джошуа Дэвис

1
@ Joshua Я думаю, я делаю это так, потому что мои интеграционные тесты занимают не менее 5 минут, и я запускаю mvn clean install много раз в день, потому что мне нужно обновить свои артефакты в локальном репозитории Maven. Согласно тому, что люди говорят выше, запуск 'install' приведет к запуску фазы интеграционного тестирования, что приведет к потере драгоценного времени разработчика.
Хорхе

Хм ... не уверен насчет 'install' запускающего интеграционного теста. В любом случае я бы все равно использовал фазу вместо профиля. Профили лучше использовать для таких вещей, как поддержка различных серверов приложений и т. Д.
Джошуа Дэвис,

1
Я пойду дальше и поиграю с этим потом. Спасибо за совет!
Хорхе

@jorge Полагаю, правильная цель здесь будет подтверждена, верно?
Килокан

1

Вы можете следовать документации maven, чтобы запускать модульные тесты со сборкой и запускать интеграционные тесты отдельно.

<project>
    <properties>
        <skipTests>true</skipTests>
    </properties>
    [...]
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.20.1</version>
                <configuration>
                    <skipITs>${skipTests}</skipITs>
                </configuration>
            </plugin>
        </plugins>
    </build>
    [...]
</project>

Это позволит вам работать со всеми интеграционными тестами, отключенными по умолчанию. Чтобы запустить их, вы используете эту команду:

mvn install -DskipTests=false

0

Вы должны использовать плагин maven surefire для запуска модульных тестов и плагин maven failsafe для запуска интеграционных тестов.

Пожалуйста, следуйте ниже, если вы хотите переключить выполнение этих тестов, используя флаги.

Конфигурация Maven

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <skipTests>${skipUnitTests}</skipTests>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <configuration>
                <includes>
                    <include>**/*IT.java</include>
                </includes>
                <skipTests>${skipIntegrationTests}</skipTests>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

        <properties>
            <skipTests>false</skipTests>
            <skipUnitTests>${skipTests}</skipUnitTests>
            <skipIntegrationTests>${skipTests}</skipIntegrationTests>
        </properties>

Таким образом, тесты будут пропущены или переключены в соответствии с приведенными ниже правилами флага:

Тесты могут быть пропущены по нижеуказанным флагам:

  • -DskipTests пропускает как модульные, так и интеграционные тесты
  • -DskipUnitTests пропускает юнит-тесты, но выполняет интеграционные тесты
  • -DskipIntegrationTests пропускает интеграционные тесты, но выполняет модульные тесты

Запуск тестов

Запустите ниже, чтобы выполнить только юнит-тесты

mvn clean test

Вы можете выполнить приведенную ниже команду для запуска тестов (как модульных, так и интеграционных)

mvn clean verify

Чтобы запустить только интеграционные тесты, следуйте

mvn failsafe:integration-test

Или пропустите юнит-тесты

mvn clean install -DskipUnitTests

Кроме того, чтобы пропустить интеграционные тесты во время mvn install, следуйте

mvn clean install -DskipIntegrationTests

Вы можете пропустить все тесты, используя

mvn clean install -DskipTests
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.