Як запустити тести інтеграції Maven


170

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

mvn test

всі тести JUnit *Test.javaв дочірніх модулях виконуються. Коли я страчу

mvn test -Dtest=**/*Integration

жоден з Integration.javaтестів не виконується в дочірніх модулях.

Це здається мені точно такою ж командою, але те, що з -Dtest = / * Інтеграція ** не працює, відображає 0 тестів, які виконуються на батьківському рівні, яких немає жодних тестів


4
Відповідь Кіефа повинна бути прийнятою, оскільки це чинний стандарт визначення інтеграційних тестів у Мейвені.
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
Я налаштував це, як ви сказали, і тільки * Тестувати не * Integration.java файли будуть працювати при виконанні: mvn install мені потрібно запустити * Test.java як за замовчуванням, але для моєї збірки nightlty мені потрібно запустити і тест * Test .java та * Integration.java. Мені потрібно виконати mvn install, а потім cd до кожної дочірньої директорії та виконати mvn -Dtest = ** / * Інтеграційний тест
Пітер Делані

66
Ви повинні використовувати плагін Fail-safe для тестування інтеграції, а не плагін, що захищається. Це не призведе до провалу збірки до тих пір , після того, як фаза після інтеграції завершена; що дозволяє вам зруйнувати тестові ресурси (наприклад, веб-сервер) до того, як збірка не вийде. Отже, безвідмовно.
Джон Гордон

для мене, як частина передінтеграційної фази, запускається сервіс jetty. Останній рядок журналу: [INFO] Запущений Jetty Server. Після цього нічого не відбувається. Він застрягає. плагін maven surefire failsafe не виконує тести, ані сервер приставки не зупиняється. Будь-яка ідея, що не так? Я використовую ту саму конфігурацію, що і вказана вами.
Тарун Кумар

6
Ця відповідь застаріла і її слід оновлювати чи видаляти.
Зак Томпсон

Будь-яка допомога в цьому? stackoverflow.com/questions/48639730 / ...
Рохіт Barnwal

250

Складання Життєвий цикл Maven тепер включає в себе етап «Інтеграція-тест» для виконання тестів інтеграції, які працюють окремо від одиничних випробувань , запущеним в фазі «тест». Він запускається після "пакету", тому якщо ви запускаєте "mvn verify", "mvn install" або "mvn install", тести інтеграції будуть запущені по цьому шляху.

За замовчуванням інтеграція-тест запускає тестові класи з назвою **/IT*.java,**/*IT.java і **/*ITCase.java, але це може бути налаштоване.

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


1
@WillV Правильно. Кладовище Кодгауза. А плагін maven-failsafe зараз у Apache. Вибачте. :)
Джин Квон

38
За замовчуванням mvn integration-testтакож виконуються одиничні тести (за допомогою верифікатора), але mvn failsafe:integration-testвиконуються лише несправні безпечні тести інтеграції.
Shadow Man

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

1
Якщо вона працює після packageфази, це означає, що я повинен помістити весь свій вихідний код ІТ-Java src/main/javaзамість src/test/javaправа?
Брюс Нд

5
@HennoVermeulen Мене бентежило те, як назвати тести. Це описано у Включеннях та Виключеннях тестів . Приємно, що параметри за замовчуванням можуть бути відмінені, але було б добре, якби вони згадували про типові параметри раніше.
Джошуа Тейлор

63

Я зробив ТОЧНО те, що ви хочете зробити, і це чудово працює. Тестові одиниці "* Тести" завжди виконуються, а "* 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%
Nils Schmidt

2
Тоді не соромтесь встановити прапорець на відповідь!
HDave

для мене, як частина передінтеграційної фази, запускається сервіс jetty. Останній рядок журналу: [INFO] Запущений Jetty Server. Після цього нічого не відбувається. Він застрягає. плагін maven surefire failsafe не виконує тести, ані сервер приставки не зупиняється. Будь-яка ідея, що не так? Я використовую ту саму конфігурацію, що і вказана вами.
Тарун Кумар

@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 Unit

Краса цього рішення полягає в тому, що насправді нічого не змінюється для одиничної тестової сторони речей.
Ми просто додаємо деяку конфігурацію до плагіна 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.
Цього разу, як і запущені одиничні тести, тести інтеграції виконуються під час фази тесту інтеграції.


Я думав, що JUnit більше не має для мене секретів. Гарне місце!
Гертас

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.java - включає всі його підкаталоги та всі файли файлів Java, які закінчуються на "Тест".
  • \*\*/\*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
Це не "десь у назві класу", а "ім'я класу закінчується тестом", наприклад, працює 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 integration-testing' буде включати в себе тести інтеграції (я також ігнорую свої тестові інтеграції в постановці). Крім того, у мене є сервер CI, який щовечора запускає мої інтеграційні тести, і для цього я видаю команду 'mvn test -P інтеграція-тести' .


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

1
@ Джошуа, я думаю, я роблю це таким чином, оскільки мої інтеграційні тести займають щонайменше 5 хвилин, і я випускаю 'mvn clean install' багато разів на день, тому що мені потрібно оновлювати свої артефакти в моєму місцевому ревізі Maven. Згідно з тим, що люди говорять вище, запуск «встановлення» призведе до запуску фази тесту інтеграції, що призведе до того, що я втрачу дорогоцінний час для розробника.
Хорхе

Хм ... не впевнений, що "встановити" працює інтеграційний тест. У будь-якому випадку я все-таки використовую фазу замість профілю. Профілі краще використовувати для таких речей, як підтримка різних серверів додатків тощо
Joshua Davis,

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.