Jak uruchomić testy integracji Maven

170

Mam projekt wielomodułowy maven2, aw każdym z moich modułów podrzędnych mam testy JUnit, które są nazwane Test.javaoraz odpowiednio Integration.javadla testów jednostkowych i testów integracji. Kiedy wykonuję:

mvn test

wszystkie testy JUnit *Test.javaw modułach potomnych są wykonywane. Kiedy wykonuję

mvn test -Dtest=**/*Integration

żaden z Integration.javatestów nie zostanie wykonany w ramach modułów potomnych.

Wydaje mi się, że jest to dokładnie to samo polecenie, ale to z opcją -Dtest = / * Integration ** nie działa, wyświetla 0 testów uruchamianych na poziomie nadrzędnym, których nie ma żadnych testów

Peter Delaney
źródło
4
Odpowiedź Kiefa powinna być akceptowana, ponieważ jest to obecny standard definiowania testów integracyjnych w Maven.
heenenee

Odpowiedzi:

110

Możesz skonfigurować Maven's Surefire do osobnego uruchamiania testów jednostkowych i testów integracji. W fazie standardowych testów jednostkowych uruchamiasz wszystko, co nie pasuje do wzorca testu integracji. Następnie tworzysz drugą fazę testową, która uruchamia tylko testy integracji.

Oto przykład:

    <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>
serg10
źródło
1
Skonfigurowałem to tak, jak powiedziałeś i tylko pliki * Test, a nie * Integration.java będą działać podczas wykonywania: mvn install Muszę domyślnie uruchomić plik * Test.java, ale dla mojej kompilacji nightlty muszę uruchomić oba * Test .java i * Integration.java. Muszę wykonać instalację mvn, a następnie cd do każdego podkatalogu podrzędnego i wykonać mvn -Dtest = ** / * Test integracji
Peter Delaney
66
Do testowania integracji należy używać wtyczki Fail-safe, a nie wtyczki typu sure-fire. To nie zawiedzie kompilacji aż po fazę post-integracja jest kompletna; pozwala ci zburzyć zasoby testowe (na przykład serwer WWW), zanim kompilacja się nie powiedzie. Stąd niezawodne.
John Gordon
dla mnie w ramach fazy przed integracją startuje serwer molo. Ostatni wiersz dziennika to: [INFO] Uruchomiono serwer Jetty. Potem nic się nie dzieje. Utknęło. Maven surefire failafe plugin nie wykonuje testów ani nie zatrzymuje serwera. Masz jakiś pomysł, co się stało? Używam tej samej konfiguracji, jaką określiłeś.
Tarun Kumar
6
Ta odpowiedź jest bardzo nieaktualna i powinna zostać zaktualizowana lub usunięta.
Zac Thompson,
Jakaś pomoc z tym? stackoverflow.com/questions/48639730/…
Rohit Barnwal
250

Cykl życia kompilacji Maven obejmuje teraz fazę „testów integracji” do uruchamiania testów integracyjnych, które są uruchamiane niezależnie od testów jednostkowych uruchamianych w fazie „testowej”. Działa po „pakiecie”, więc jeśli uruchomisz „mvn verify”, „mvn install” lub „mvn deploy”, po drodze zostaną przeprowadzone testy integracji.

Domyślnie integracja test prowadzi zajęcia testowe nazwane **/IT*.java, **/*IT.javai **/*ITCase.java, ale to może być skonfigurowany.

Szczegółowe informacje na temat okablowania tego wszystkiego, zobaczyć Failsafe wtyczki , w stronę wykorzystania Failsafe (nie prawidłowo połączony z poprzedniej strony, jak to piszę), a także sprawdzić tę Sonatype blogu .

Kief
źródło
1
@WillV Correct. Cmentarz Codehaus. A wtyczka maven-failafe-plugin jest teraz w Apache. Przepraszam. :)
Jin Kwon
38
Domyślnie mvn integration-testuruchamia również testy jednostkowe (przy użyciu metody surefire), ale mvn failsafe:integration-testuruchamia tylko testy integracji odporne na uszkodzenia.
Shadow Man
22
Niesamowite, że dokumentacja wtyczki Failsafe, strona użytkowania i często zadawane pytania nie wspominają, że uruchamia klasy testowe o nazwach * / IT .java, ** / * IT.java i ** / * ITCase.java ...
Vermeulen
1
Jeśli działa po packagefazie, oznacza to, że powinienem umieścić cały mój kod źródłowy Java IT pod src/main/javazamiast w src/test/javaprawo?
Bruce Sun,
5
@HennoVermeulen Nie wiedziałem, jak nazwać testy. Jest to opisane w sekcji Włączenia i wyłączenia testów . Fajnie, że wartości domyślne można zastąpić, ale byłoby miło, gdyby wcześniej wspomnieli o wartościach domyślnych.
Joshua Taylor
63

Zrobiłem DOKŁADNIE to, co chcesz i działa świetnie. Testy jednostkowe „* Testy” są zawsze uruchamiane, a „* IntegrationTests” działają tylko wtedy, gdy wykonujesz weryfikację mvn lub instalację mvn. Tutaj jest fragment mojego POM. serg10 prawie miał rację… ale nie całkiem.

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

Powodzenia!

HDave
źródło
Dokładnie to, co próbowałem zrobić, ale moje testy integracyjne działały podczas fazy testowej mvn, ponieważ NIE POMIŁEM DOMYŚLNYCH. Myślałem, że skonfigurowanie wykonania testu zastąpi to. Jak wyjaśniłeś, po prostu dodaje nowe wykonanie (w ten sposób wszystko działałoby dwukrotnie). Więc dla mnie brakowało skipu. +1 Ponieważ ta konfiguracja odpowiada na pytanie w 100%
Nils Schmidt
2
Następnie zaznacz pole wyboru, aby ta odpowiedź była odpowiedzią!
HDave
dla mnie w ramach fazy przed integracją startuje serwer molo. Ostatni wiersz dziennika to: [INFO] Uruchomiono serwer Jetty. Potem nic się nie dzieje. Utknęło. Maven surefire failafe plugin nie wykonuje testów ani nie zatrzymuje serwera. Masz jakiś pomysł, co się stało? Używam tej samej konfiguracji, jaką określiłeś.
Tarun Kumar
@Tarun - zadaj nowe pytanie dotyczące Twojego problemu
HDave
2
To powinna być akceptowana odpowiedź. Powiązany cel maven to: clean compile integration-test -Dmaven.test.failure.ignore=false
Neill Lima
31

Możesz je bardzo łatwo podzielić za pomocą kategorii JUnit i Maven.
Pokazano to bardzo, bardzo krótko poniżej, dzieląc testy jednostkowe i integracyjne.

Zdefiniuj interfejs znacznika

Pierwszym krokiem w grupowaniu testu za pomocą kategorii jest utworzenie interfejsu znaczników.
Ten interfejs będzie używany do oznaczania wszystkich testów, które chcesz uruchomić, jako testy integracji.

public interface IntegrationTest {}

Zaznacz swoje klasy testowe

Dodaj adnotację kategorii na początku klasy testowej. Przyjmuje nazwę nowego interfejsu.

import org.junit.experimental.categories.Category;

@Category(IntegrationTest.class)
public class ExampleIntegrationTest{

    @Test
    public void longRunningServiceTest() throws Exception {
    }

}

Skonfiguruj testy jednostkowe Maven

Piękno tego rozwiązania polega na tym, że nic tak naprawdę nie zmienia się po stronie testów jednostkowych.
Po prostu dodajemy konfigurację do wtyczki maven surefire, aby ignorowała wszelkie testy integracji.

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

Gdy to zrobisz mvn clean test, zostaną uruchomione tylko nieoznaczone testy jednostkowe.

Skonfiguruj testy integracji Maven

Ponownie konfiguracja tego jest bardzo prosta.
Używamy standardowej, bezpiecznej wtyczki i konfigurujemy ją tak, aby uruchamiała tylko testy integracyjne.

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

Konfiguracja korzysta ze standardowego celu wykonania, aby uruchomić bezpieczną wtyczkę w fazie testów integracji podczas kompilacji.

Możesz teraz zrobić mvn clean install.
Tym razem, oprócz uruchomionych testów jednostkowych, testy integracji są uruchamiane w fazie testów integracji.

John Dobie
źródło
Myślałem, że JUnit nie ma już dla mnie tajemnic. Dobre miejsce!
gertas
4
Działa to tylko wtedy, gdy interfejs znacznika już istnieje gdzieś dostępny dla Mavena. Nie działa, jeśli interfejs znacznika istnieje w innym module tej samej kompilacji wielomodułowej.
EngineerBetter_DJ
@EngineerBetter_DJ co przez to rozumiesz? Nie możesz tego zrobić, jeśli masz konfigurację Mavena opartą na wielu projektach?
matthieusb
16

Powinieneś spróbować użyć bezpiecznej wtyczki maven . Możesz powiedzieć, aby zawierał określony zestaw testów.

James Kingsbery
źródło
1
+1 To jest to, czego używam. Działa dobrze i umożliwia wykonanie konfiguracji przed / po, takiej jak uruchamianie i zamykanie lokalnego kontenera serwletów.
mdma
maven-failsafe-pluginudał się na Plugin Graveyard
Jin Kwon
9
Strona cmentarza informuje właśnie o przeniesieniu failsafewtyczki do maven-failsafe-plugin. Wygląda na maven-failsafe-pluginto, że jest nadal aktywny (dokumenty zostały ostatnio przesłane w marcu 2014 r.).
James Kingsbery,
13

Domyślnie Maven uruchamia tylko testy, które mają gdzieś Test w nazwie klasy.

Zmień nazwę na IntegrationTest i prawdopodobnie zadziała.

Alternatywnie możesz zmienić konfigurację Mavena, aby uwzględnić ten plik, ale prawdopodobnie łatwiej i lepiej jest nazwać testy SomethingTest.

Z włączeń i wyłączeń testów :

Domyślnie wtyczka Surefire automatycznie uwzględni wszystkie klasy testowe z następującymi wzorami symboli wieloznacznych:

  • \*\*/Test\*.java - zawiera wszystkie jego podkatalogi i wszystkie nazwy plików java zaczynające się od „Test”.
  • \*\*/\*Test.java - zawiera wszystkie swoje podkatalogi i wszystkie nazwy plików java kończące się na „Test”.
  • \*\*/\*TestCase.java - zawiera wszystkie jego podkatalogi i wszystkie nazwy plików java kończące się na „TestCase”.

Jeśli klasy testowe nie są zgodne z konwencją nazewnictwa, skonfiguruj wtyczkę Surefire i określ testy, które chcesz dołączyć.

cletus
źródło
Cześć i dziękuję Mam dwa rodzaje testów, normalne testy POJO Junit o nazwie SomethingTest.java, które są uruchamiane. Mam też testy integracyjne o nazwie SomethingIntegration.java, które nie dają się zwolnić. Plik SomethingTest.java jest uruchamiany za pośrednictwem testu mvn lub instalacji mvn. Drugie testy nie dają się zwolnić. mvn test -Dtest = ** / * Integracja
Peter Delaney
.. i przez „Maven uruchamia tylko testy, które mają Test gdzieś w nazwie klasy” masz na myśli „wtyczka Maven surefire uruchamia tylko testy, które mają Test gdzieś w nazwie klasy”.
Joshua Davis,
1
To nie jest „gdzieś w nazwie klasy”, jej „nazwa klasy kończy się na Test”, na przykład MyTest działa, ale MyTests nie
Julian
10

Innym sposobem przeprowadzania testów integracyjnych z Mavenem jest skorzystanie z funkcji profilu:

...
<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>
...

Uruchomienie „mvn clean install” uruchomi domyślną kompilację. Jak określono powyżej, testy integracji zostaną zignorowane. Uruchomienie `` mvn clean install -P Integration-tests '' będzie zawierało testy integracji (ignoruję również pomostowe testy integracji). Co więcej, mam serwer CI, który każdego wieczoru przeprowadza moje testy integracyjne iw tym celu wydaję polecenie „mvn test -P Integration-tests” .

Jorge
źródło
1
Dlaczego nie miałbyś skorzystać z fazy testów integracji? Profile mogą być następnie używane do takich rzeczy, jak testowanie integracji z różnymi serwerami aplikacji itp., Tak jak robi to Arquillian. Nie jestem ekspertem od Maven, ale myślę, że eksperci mogą powiedzieć, że nie jest to zbyt „Maven-y”.
Joshua Davis,
1
@Joshua Myślę, że robię to w ten sposób, ponieważ moje testy integracji trwają co najmniej 5 minut, a ja wykonuję „czystą instalację mvn” wiele razy dziennie, ponieważ muszę zaktualizować moje artefakty w lokalnym repozytorium maven. Zgodnie z tym, co ludzie mówią powyżej, uruchomienie „instalacji” spowoduje uruchomienie fazy testów integracji, przez co stracę cenny czas programisty.
Jorge
Hmm ... nie jestem pewien co do uruchomienia testu integracji „zainstaluj”. W każdym razie nadal używałbym fazy zamiast profilu. Profile lepiej nadają się do takich rzeczy, jak obsługa różnych serwerów aplikacji itp.
Joshua Davis,
1
Pójdę dalej i pobawię się tym. Dzięki za radę!
Jorge,
@jorge Wydaje mi się, że właściwym celem do użycia tutaj byłoby zweryfikowanie, prawda?
Kilokahn
1

Możesz postępować zgodnie z dokumentacją mavena aby uruchomić testy jednostkowe z kompilacją i osobno uruchomić testy integracji.

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

Umożliwi to uruchamianie z domyślnie wyłączonymi wszystkimi testami integracji. Aby je uruchomić, użyj tego polecenia:

mvn install -DskipTests=false
Dherik
źródło
0

Powinieneś użyć wtyczki maven surefire do uruchamiania testów jednostkowych i wtyczki maven failafe do uruchamiania testów integracyjnych.

Postępuj zgodnie z poniższymi instrukcjami, jeśli chcesz przełączyć wykonywanie tych testów za pomocą flag.

Konfiguracja Mavena

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

Tak więc testy zostaną pominięte lub przełączone zgodnie z poniższymi zasadami flagi:

Testy można pominąć, korzystając z poniższych flag:

  • -DskipTests pomija testy jednostkowe i integracyjne
  • -DskipUnitTests pomija testy jednostkowe, ale wykonuje testy integracji
  • -DskipIntegrationTests pomija testy integracyjne, ale wykonuje testy jednostkowe

Uruchomione testy

Uruchom poniżej, aby wykonać tylko testy jednostkowe

mvn clean test

Możesz wykonać poniższe polecenie, aby uruchomić testy (zarówno jednostkowe, jak i integracyjne)

mvn clean verify

Aby uruchomić tylko testy integracji, wykonaj następujące czynności

mvn failsafe:integration-test

Lub pomiń testy jednostkowe

mvn clean install -DskipUnitTests

Ponadto, aby pominąć testy integracyjne w trakcie mvn install, wykonaj

mvn clean install -DskipIntegrationTests

Możesz pominąć wszystkie testy za pomocą

mvn clean install -DskipTests
Liquidpie
źródło