Come posso eseguire i miei test di integrazione Maven


170

Ho un progetto multi-modulo maven2 e in ciascuno dei miei moduli figlio ho test JUnit che sono nominati Test.javae rispettivamente Integration.javaper unit test e test di integrazione. Quando eseguo:

mvn test

*Test.javavengono eseguiti tutti i test JUnit all'interno dei moduli figlio. Quando eseguo

mvn test -Dtest=**/*Integration

nessuno dei Integration.javatest viene eseguito all'interno dei moduli figlio.

Mi sembrano esattamente lo stesso comando ma quello con l' opzione -Dtest = / * Integration ** non funziona, visualizza 0 test in esecuzione a livello genitore, che non ci sono test


4
La risposta di Kief dovrebbe essere quella accettata, in quanto è lo standard attuale per la definizione dei test di integrazione in Maven.
Heenenee,

Risposte:


110

È possibile configurare Maven's Surefire per eseguire separatamente unit test e test di integrazione. Nella fase di unit test standard si esegue tutto ciò che non corrisponde a un test di integrazione. Quindi si crea una seconda fase di test che esegue solo i test di integrazione.

Ecco un esempio:

    <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
Ho configurato questo come hai detto e solo il * Test non i file * Integration.java verranno eseguiti durante l'esecuzione: installazione mvn Ho bisogno di eseguire il mio * Test.java come predefinito, ma per la mia build notturna devo eseguire entrambi * Test .java e * Integration.java. Devo eseguire mvn install quindi cd in ogni directory secondaria figlio ed eseguire mvn -Dtest = ** / * Test di integrazione
Peter Delaney,

66
È necessario utilizzare il plug-in Fail-safe per i test di integrazione, non il plug-in sure-fire. Non mancherà la costruzione fino a quando , dopo la fase di post-integrazione è completa; permettendoti di abbattere le risorse di test (un web server, ad esempio) prima che la compilazione fallisca. Quindi, a prova di errore.
John Gordon,

per me, nell'ambito della fase di pre-integrazione, viene avviato jetty server. L'ultima riga del registro è: [INFO] Jetty Server avviato. Dopo ciò, non succede nulla. Si blocca. il plug-in di sicurezza fail-safe non esegue test né si ferma il server del molo. Qualche idea di cosa c'è che non va? Sto usando la stessa configurazione specificata da te.
Tarun Kumar,

6
Questa risposta è molto obsoleta e dovrebbe essere aggiornata o rimossa.
Zac Thompson,


250

Il ciclo di vita della build Maven ora include la fase "test di integrazione" per l'esecuzione dei test di integrazione, che vengono eseguiti separatamente dai test dell'unità durante la fase di "test". Viene eseguito dopo "pacchetto", quindi se si esegue "mvn verifica", "mvn installa" o "mvn deploy", i test di integrazione verranno eseguiti lungo il percorso.

Per impostazione predefinita, l'integrazione-test viene eseguito classi di test di nome **/IT*.java, **/*IT.javae **/*ITCase.java, ma questo può essere configurato.

Per i dettagli su come collegare tutto, vedere il plug-in Failsafe , la pagina di utilizzo Failsafe (non collegata correttamente dalla pagina precedente mentre scrivo questo) e controllare anche questo post sul blog Sonatype .


1
@WillV Correct. Il cimitero del Codehaus. E il plugin maven-fail-safe è ora in Apache. Scusate. :)
Jin Kwon,

38
Per impostazione predefinita, mvn integration-testesegue anche test unitari (usando via surefire) ma mvn failsafe:integration-testesegue solo i test di integrazione fail-safe.
Shadow Man,

22
Incredibilmente, la documentazione del plug-in Failsafe, la pagina di utilizzo e le FAQ non menzionano che esegue classi di test denominate * / IT .java, ** / * IT.java e ** / * ITCase.java ...
Henno Vermeulen

1
Se viene eseguito dopo packagefase, ciò significa che dovrei mettere tutto il mio codice sorgente Java IT src/main/javainvece di src/test/javagiusto?
Bruce Sun,

5
@HennoVermeulen Ero confuso anche su come nominare i test. È descritto in Inclusioni ed esclusioni di test . È bello che le impostazioni predefinite possano essere ignorate, ma sarebbe bello se prima menzionassero le impostazioni predefinite.
Joshua Taylor,

63

Ho fatto ESATTAMENTE quello che vuoi fare e funziona benissimo. I test unitari "* Test" vengono sempre eseguiti e "* IntegrationTests" viene eseguito solo quando si esegue una verifica mvn o installazione mvn. Eccolo lo snippet del mio POM. serg10 aveva quasi ragione ... ma non del tutto.

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

In bocca al lupo!


Esattamente quello che ho provato a fare, ma i miei test di integrazione hanno continuato a funzionare durante la fase di test di mvn, poiché NON HO SALTO IL DEFAULT. Ho pensato che la configurazione dell'esecuzione del test avrebbe avuto la precedenza. Come hai spiegato, aggiunge solo una nuova esecuzione (quindi tutto verrebbe eseguito due volte). Quindi per me mancava il pezzo da saltare. +1 Poiché questa configurazione risponde alla domanda al 100%
Nils Schmidt il

2
Quindi sentiti libero di selezionare la casella per questa risposta come risposta!
HDave

per me, nell'ambito della fase di pre-integrazione, viene avviato jetty server. L'ultima riga del registro è: [INFO] Jetty Server avviato. Dopo ciò, non succede nulla. Si blocca. il plug-in di sicurezza fail-safe non esegue test né si ferma il server del molo. Qualche idea di cosa c'è che non va? Sto usando la stessa configurazione specificata da te.
Tarun Kumar,

@Tarun - fai una nuova domanda sul tuo problema
HDave il

2
Questa dovrebbe essere la risposta accettata. L'obiettivo del maven associato è: clean compile integration-test -Dmaven.test.failure.ignore=false
Neill Lima,

31

Puoi dividerli molto facilmente usando le categorie JUnit e Maven.
Ciò è mostrato molto, molto brevemente di seguito dalla divisione dell'unità e dai test di integrazione.

Definire un'interfaccia marker

Il primo passo nel raggruppare un test usando le categorie è creare un'interfaccia marker.
Questa interfaccia verrà utilizzata per contrassegnare tutti i test che si desidera eseguire come test di integrazione.

public interface IntegrationTest {}

Segna le tue lezioni di prova

Aggiungi l'annotazione di categoria all'inizio della classe di test. Prende il nome della tua nuova interfaccia.

import org.junit.experimental.categories.Category;

@Category(IntegrationTest.class)
public class ExampleIntegrationTest{

    @Test
    public void longRunningServiceTest() throws Exception {
    }

}

Configurare i test dell'unità Maven

Il bello di questa soluzione è che nulla cambia davvero per il lato unit test delle cose.
Aggiungiamo semplicemente un po 'di configurazione al plugin maven surefire per farlo ignorare qualsiasi test di integrazione.

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

Quando mvn clean testesegui una, verranno eseguiti solo i test unitari non contrassegnati.

Configurare i test di integrazione Maven

Ancora una volta la configurazione per questo è molto semplice.
Utilizziamo il plug-in fail-safe standard e lo configuriamo per eseguire solo i test di integrazione.

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

La configurazione utilizza un obiettivo di esecuzione standard per eseguire il plug-in fail-safe durante la fase di test di integrazione della build.

Ora puoi fare un mvn clean install.
Questa volta, nonché i test unitari in esecuzione, i test di integrazione vengono eseguiti durante la fase di test di integrazione.


Pensavo che JUnit non avesse più segreti per me. Buon posto!
Gertas,

4
Funziona solo se l'interfaccia del marker esiste già da qualche parte disponibile per Maven. Non funziona se l'interfaccia del marker esiste in un altro modulo della stessa build multi-modulo.
EngineerBetter_DJ

@EngineerBetter_DJ cosa intendi con questo? Non puoi farlo se hai una configurazione Maven basata su più progetti?
Matthieusb,

16

Dovresti provare a usare il plugin Maven fail-safe . Puoi dirlo per includere un certo set di test.


1
+1 Questo è quello che uso. Funziona bene e consente di eseguire l'installazione pre / post, ad esempio l'avvio e l'arresto di un contenitore servlet locale.
mdma,

maven-failsafe-pluginè andato al Plugin Graveyard
Jin Kwon il

9
La pagina del cimitero dice solo che il failsafeplugin è stato spostato maven-failsafe-plugin. Sembra che maven-failsafe-pluginsia ancora attivo (i documenti sono stati spinti l'ultima volta a marzo 2014).
James Kingsbery,

13

Per impostazione predefinita, Maven esegue solo test che hanno Test da qualche parte nel nome della classe.

Rinomina in IntegrationTest e probabilmente funzionerà.

In alternativa puoi cambiare la configurazione di Maven per includere quel file, ma è probabilmente più facile e meglio solo nominare i tuoi test SomethingTest.

Da inclusioni ed esclusioni di test :

Per impostazione predefinita, il plug-in Surefire includerà automaticamente tutte le classi di test con i seguenti pattern jolly:

  • \*\*/Test\*.java - include tutta la sua sottodirectory e tutti i nomi di file Java che iniziano con "Test".
  • \*\*/\*Test.java - include tutta la sua sottodirectory e tutti i nomi di file java che terminano con "Test".
  • \*\*/\*TestCase.java - include tutta la sua sottodirectory e tutti i nomi di file java che terminano con "TestCase".

Se le classi di test non sono conformi alla convenzione di denominazione, configurare il plug-in Surefire e specificare i test che si desidera includere.


Ciao e grazie ho due tipi di test normali test POJO Junit chiamati SomethingTest.java che vengono licenziati. Ho anche test di integrazione chiamati SomethingIntegration.java che non vengono licenziati. SomethingTest.java viene attivato tramite mvn test o mvn install. I secondi test non vengono licenziati. mvn test -Dtest = ** / * Integration
Peter Delaney,

.. e con "Maven esegue solo test che hanno Test da qualche parte nel nome della classe" intendi "il plugin Maven surefire esegue solo test che hanno Test da qualche parte nel nome della classe".
Joshua Davis,

1
Non è "da qualche parte nel nome della classe" è "il nome della classe termina con Test", ad esempio MyTest funziona ma MyTest no
Julian

10

Un altro modo di eseguire test di integrazione con Maven è utilizzare la funzione profilo:

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

L'esecuzione di "mvn clean install" eseguirà la build predefinita. Come specificato sopra, i test di integrazione verranno ignorati. L'esecuzione di 'mvn clean install -P test di integrazione' includerà i test di integrazione (ignoro anche i miei test di integrazione di gestione temporanea). Inoltre, ho un server CI che esegue i miei test di integrazione ogni notte e per questo motivo emetto il comando 'mvn test -P integrazione-test' .


1
Perché non utilizzare la fase di test di integrazione? I profili possono quindi essere utilizzati per cose come i test di integrazione con vari server di app, ecc. Come Arquillian. Non sono un esperto di Maven, ma penso che gli esperti potrebbero dire che non è molto "Maven-y".
Joshua Davis,

1
@Joshua Immagino di farlo in questo modo perché i miei test di integrazione impiegano almeno 5 minuti per essere eseguiti e lancio 'mvn clean install' più volte al giorno perché devo aggiornare i miei artefatti nel mio repo locale di Maven. Secondo quanto affermato in precedenza, l'esecuzione di 'install' causerà l'esecuzione della fase di test di integrazione causandomi la perdita di tempo prezioso per gli sviluppatori.
Jorge,

Hmm ... non sono sicuro di "installare" durante l'esecuzione del test di integrazione. In ogni caso, utilizzerei comunque la fase anziché un profilo. I profili sono meglio utilizzati per cose come il supporto di diversi server di app, ecc.
Joshua Davis,

1
Andrò avanti e ci giocherò allora. Grazie per il consiglio!
Jorge,

@jorge Immagino che l'obiettivo corretto da usare qui sarebbe verificare, giusto?
Kilokahn,

1

È possibile seguire la documentazione di Maven per eseguire i test unitari con la build ed eseguire i test di integrazione separatamente.

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

Ciò ti consentirà di eseguire tutti i test di integrazione disabilitati per impostazione predefinita. Per eseguirli, utilizzare questo comando:

mvn install -DskipTests=false

0

Dovresti usare il plugin maven surefire per eseguire i test unitari e il plugin fail-safe maven per eseguire i test di integrazione.

Seguire di seguito se si desidera attivare / disattivare l'esecuzione di questi test utilizzando i flag.

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

Quindi, i test verranno saltati o scambiati secondo le regole di bandiera seguenti:

I test possono essere ignorati dalle bandiere seguenti:

  • -DskipTests salta sia i test unitari che quelli di integrazione
  • -DskipUnitTests salta i test unitari ma esegue i test di integrazione
  • -DskipIntegrationTests salta i test di integrazione ma esegue i test unitari

Test in corso

Eseguire di seguito per eseguire solo Test unità

mvn clean test

È possibile eseguire il comando seguente per eseguire i test (sia unità che integrazione)

mvn clean verify

Per eseguire solo i test di integrazione, seguire

mvn failsafe:integration-test

Oppure salta i test unitari

mvn clean install -DskipUnitTests

Inoltre, per saltare i test di integrazione durante mvn install, seguire

mvn clean install -DskipIntegrationTests

Puoi saltare tutti i test usando

mvn clean install -DskipTests
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.