Comment exécuter mes tests d'intégration Maven

170

J'ai un projet multi-module maven2 et dans chacun de mes modules enfants j'ai des tests JUnit qui sont nommés Test.javaet Integration.javapour les tests unitaires et les tests d'intégration respectivement. Quand j'exécute:

mvn test

tous les tests JUnit *Test.javades modules enfants sont exécutés. Quand j'exécute

mvn test -Dtest=**/*Integration

aucun des Integration.javatests n'est exécuté dans les modules enfants.

Celles-ci me semblent être exactement la même commande mais celle avec -Dtest = / * Integration ** ne fonctionne pas, elle affiche 0 test en cours d'exécution au niveau parent, il n'y a pas de tests

Peter Delaney
la source
4
La réponse de Kief devrait être acceptée, car c'est la norme actuelle pour définir les tests d'intégration dans Maven.
heenenee

Réponses:

110

Vous pouvez configurer Surefire de Maven pour exécuter des tests unitaires et des tests d'intégration séparément. Dans la phase de test unitaire standard, vous exécutez tout ce qui ne correspond pas à un test d'intégration. Vous créez ensuite une deuxième phase de test qui exécute uniquement les tests d'intégration.

Voici un exemple:

    <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
la source
1
J'ai configuré cela comme vous l'avez dit et seuls les fichiers * Test et non les fichiers * Integration.java seront exécutés lors de l'exécution: mvn install Je dois exécuter mon * Test.java par défaut, mais pour ma version nightlty, je dois exécuter les deux * Test .java et * Integration.java. Je dois exécuter mvn install puis cd dans chaque répertoire sous-enfant et exécuter mvn -Dtest = ** / * Test d'intégration
Peter Delaney
66
Vous devez utiliser le plugin Fail-safe pour les tests d'intégration, pas le plugin sure-fire. Il n'échouera pas la construction tant que la phase de post-intégration ne sera pas terminée; vous permettant de supprimer des ressources de test (un serveur Web, par exemple) avant l'échec de la construction. Par conséquent, à sécurité intégrée.
John Gordon
pour moi, dans le cadre de la phase de pré-intégration, le serveur de jetée démarre. La dernière ligne du journal est: [INFO] Démarrage de Jetty Server. Après cela, rien ne se passe. Il reste bloqué. Le plugin de sécurité maven surefire n'exécute pas de tests ni ne s'arrête sur le serveur de jetée. Une idée de ce qui ne va pas? J'utilise la même configuration que celle spécifiée par vous.
Tarun Kumar
6
Cette réponse est très obsolète et devrait être mise à jour ou supprimée.
Zac Thompson
Une aide avec celui-ci? stackoverflow.com/questions/48639730/…
Rohit Barnwal
250

Le cycle de vie des builds Maven inclut désormais la phase de «test d'intégration» pour l'exécution des tests d'intégration, qui sont exécutés séparément des tests unitaires exécutés pendant la phase de «test». Il s'exécute après "package", donc si vous exécutez "mvn verify", "mvn install" ou "mvn deploy", des tests d'intégration seront exécutés en cours de route.

Par défaut, l' intégration test exécute les classes de test nommés **/IT*.java, **/*IT.javaet **/*ITCase.java, mais cela peut être configuré.

Pour plus de détails sur la façon de câbler tout cela, consultez le plugin Failsafe , la page d'utilisation Failsafe (pas correctement liée à la page précédente au moment où j'écris ceci), et consultez également ce billet de blog Sonatype .

Kief
la source
1
@ WillV Correct. Le cimetière du Codehaus. Et le plugin maven-failafe-plugin est maintenant dans Apache. Désolé. :)
Jin Kwon
38
Par défaut, mvn integration-testexécute également des tests unitaires (en utilisant via surefire) mais n'exécute mvn failsafe:integration-testque les tests d'intégration de sécurité.
Shadow Man
22
Incroyablement, la documentation du plugin Failsafe, la page d'utilisation et la FAQ ne mentionnent pas qu'il exécute des classes de test nommées * / IT .java, ** / * IT.java et ** / * ITCase.java ...
Henno Vermeulen
1
Si cela fonctionne après la packagephase, cela signifie que je devrais mettre tout mon code source informatique Java sous src/main/javaau lieu de src/test/javadroite?
Bruce Sun
5
@HennoVermeulen Je ne savais pas non plus comment nommer les tests. Il est décrit dans Inclusions et exclusions de tests . C'est bien que les valeurs par défaut puissent être remplacées, mais ce serait bien si elles mentionnaient les valeurs par défaut plus tôt.
Joshua Taylor
63

J'ai fait EXACTEMENT ce que vous vouliez faire et cela fonctionne très bien. Les tests unitaires "* Tests" sont toujours exécutés et "* IntegrationTests" ne s'exécutent que lorsque vous effectuez une vérification mvn ou une installation mvn. Voici l'extrait de mon POM. serg10 avait presque raison ... mais pas tout à fait.

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

Bonne chance!

HDave
la source
Exactement ce que j'ai essayé de faire, mais mes tests d'intégration ont continué à s'exécuter pendant la phase de test mvn, car je n'ai PAS SAUTÉ LA DÉFAUT. Je pensais que la configuration de l'exécution du test la remplacerait. Comme vous l'avez expliqué, cela ajoute simplement une nouvelle exécution (ainsi tout s'exécuterait deux fois). Donc pour moi, le skip était une pièce manquante. +1 Comme cette configuration répond à la question à 100%
Nils Schmidt
2
Alors n'hésitez pas à cocher la case pour que cette réponse soit la réponse!
HDave
pour moi, dans le cadre de la phase de pré-intégration, le serveur de jetée démarre. La dernière ligne du journal est: [INFO] Démarrage de Jetty Server. Après cela, rien ne se passe. Il reste bloqué. Le plugin de sécurité maven surefire n'exécute pas de tests ni ne s'arrête sur le serveur de jetée. Une idée de ce qui ne va pas? J'utilise la même configuration que celle spécifiée par vous.
Tarun Kumar
@Tarun - posez une nouvelle question sur votre problème
HDave
2
Cela devrait être la réponse acceptée. L'objectif maven associé est: clean compile integration-test -Dmaven.test.failure.ignore=false
Neill Lima
31

Vous pouvez les diviser très facilement en utilisant les catégories JUnit et Maven.
Ceci est montré très, très brièvement ci-dessous par des tests unitaires et d'intégration.

Définir une interface de marqueur

La première étape du regroupement d'un test à l'aide de catégories consiste à créer une interface de marqueurs.
Cette interface sera utilisée pour marquer tous les tests que vous souhaitez exécuter comme tests d'intégration.

public interface IntegrationTest {}

Marquez vos classes de test

Ajoutez l'annotation de catégorie en haut de votre classe de test. Il prend le nom de votre nouvelle interface.

import org.junit.experimental.categories.Category;

@Category(IntegrationTest.class)
public class ExampleIntegrationTest{

    @Test
    public void longRunningServiceTest() throws Exception {
    }

}

Configurer les tests unitaires Maven

La beauté de cette solution est que rien ne change vraiment pour le côté test unitaire des choses.
Nous ajoutons simplement une configuration au plugin maven surefire pour qu'il ignore les tests d'intégration.

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

Lorsque vous effectuez un mvn clean test, seuls vos tests unitaires non marqués seront exécutés.

Configurer les tests d'intégration Maven

Là encore, la configuration est très simple.
Nous utilisons le plugin de sécurité standard et le configurons pour exécuter uniquement les tests d'intégration.

<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 configuration utilise un objectif d'exécution standard pour exécuter le plug-in de sécurité pendant la phase de test d'intégration de la construction.

Vous pouvez maintenant faire un mvn clean install.
Cette fois-ci, ainsi que les tests unitaires en cours d'exécution, les tests d'intégration sont exécutés pendant la phase de test d'intégration.

John Dobie
la source
Je pensais que JUnit n'avait plus de secrets pour moi. Bon endroit!
gertas
4
Cela ne fonctionne que si l'interface de marqueur existe déjà quelque part disponible pour Maven. Cela ne fonctionne pas si votre interface de marqueur existe dans un autre module de la même construction multi-module.
EngineerBetter_DJ
@EngineerBetter_DJ que voulez-vous dire par là? Vous ne pouvez pas faire cela si vous avez une configuration maven basée sur plusieurs projets?
matthieusb
16

Vous devriez essayer d'utiliser le plugin de sécurité maven . Vous pouvez lui dire d'inclure un certain ensemble de tests.

James Kingsbery
la source
1
+1 C'est ce que j'utilise. Fonctionne bien et vous permet d'effectuer une configuration avant / après, comme le démarrage et l'arrêt d'un conteneur de servlet local.
mdma
maven-failsafe-pluginest allé à Plugin Graveyard
Jin Kwon
9
La page du cimetière indique simplement que le failsafeplugin a été déplacé maven-failsafe-plugin. Il semble que le maven-failsafe-pluginest toujours actif (les documents ont été envoyés pour la dernière fois en mars 2014).
James Kingsbery
13

Par défaut, Maven exécute uniquement les tests qui ont Test quelque part dans le nom de la classe.

Renommez en IntegrationTest et cela fonctionnera probablement.

Vous pouvez également modifier la configuration de Maven pour inclure ce fichier, mais il est probablement plus facile et préférable de nommer vos tests SomethingTest.

Des inclusions et exclusions de tests :

Par défaut, le plug-in Surefire inclura automatiquement toutes les classes de test avec les modèles de caractères génériques suivants:

  • \*\*/Test\*.java - inclut tous ses sous-répertoires et tous les noms de fichiers java commençant par "Test".
  • \*\*/\*Test.java - inclut tous ses sous-répertoires et tous les noms de fichiers java qui se terminent par "Test".
  • \*\*/\*TestCase.java - inclut tous ses sous-répertoires et tous les noms de fichiers java qui se terminent par "TestCase".

Si les classes de test ne sont pas conformes à la convention de dénomination, configurez le plug-in Surefire et spécifiez les tests que vous souhaitez inclure.

cletus
la source
Salut et merci J'ai deux types de tests des tests POJO Junit normaux appelés SomethingTest.java qui sont déclenchés. J'ai également des tests d'intégration appelés SomethingIntegration.java qui ne sont pas déclenchés. Le SomethingTest.java est déclenché via mvn test ou mvn install. Les seconds tests ne sont pas renvoyés. mvn test -Dtest = ** / * Intégration
Peter Delaney
.. et par "Maven exécute uniquement les tests qui ont Test quelque part dans le nom de la classe" vous voulez dire "le plugin Maven surefire exécute uniquement les tests qui ont Test quelque part dans le nom de la classe".
Joshua Davis le
1
Ce n'est pas «quelque part dans le nom de la classe», c'est «le nom de la classe se termine par Test», par exemple MyTest fonctionne mais pas MyTests
Julian
10

Une autre façon d'exécuter des tests d'intégration avec Maven consiste à utiliser la fonction de profil:

...
<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'exécution de 'mvn clean install' exécutera la construction par défaut. Comme spécifié ci-dessus, les tests d'intégration seront ignorés. L'exécution de 'mvn clean install -P integration-tests' inclura les tests d'intégration ( j'ignore également mes tests d'intégration de staging). De plus, j'ai un serveur CI qui exécute mes tests d'intégration tous les soirs et pour cela j'émets la commande 'mvn test -P integration-tests' .

Jorge
la source
1
Pourquoi n'utiliseriez-vous pas la phase de test d'intégration? Les profils peuvent ensuite être utilisés pour des tâches telles que les tests d'intégration sur divers serveurs d'applications, etc., comme le fait Arquillian. Je ne suis pas un expert Maven, mais je pense que les experts pourraient dire que ce n'est pas très «Maven-y».
Joshua Davis
1
@Joshua Je suppose que je le fais de cette façon parce que mes tests d'intégration prennent au moins 5 minutes à s'exécuter et que je lance 'mvn clean install' plusieurs fois par jour parce que je dois mettre à jour mes artefacts dans mon repo maven local. Selon ce que les gens disent ci-dessus, exécuter 'install' entraînera l'exécution de la phase de test d'intégration, ce qui me fera perdre un temps précieux aux développeurs.
Jorge
Hmm ... pas sûr de "installer" en cours de test d'intégration. Dans tous les cas, j'utiliserais toujours la phase au lieu d'un profil. Les profils sont mieux utilisés pour des choses comme la prise en charge de différents serveurs d'applications, etc.
Joshua Davis
1
Je vais continuer et jouer avec ça alors. Merci pour le conseil!
Jorge
@jorge Je suppose que l'objectif correct à utiliser ici serait de vérifier, non?
Kilokahn
1

Vous pouvez suivre la documentation de maven pour exécuter les tests unitaires avec la version et exécuter les tests d'intégration séparément.

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

Cela vous permettra d'exécuter avec tous les tests d'intégration désactivés par défaut. Pour les exécuter, vous utilisez cette commande:

mvn install -DskipTests=false
Dherik
la source
0

Vous devez utiliser Maven Surefire plug - in pour exécuter des tests unitaires et Maven plug - in failsafe pour exécuter des tests d'intégration.

Veuillez suivre ci-dessous si vous souhaitez basculer l'exécution de ces tests à l'aide d'indicateurs.

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

Ainsi, les tests seront ignorés ou commutés selon les règles de drapeau ci-dessous:

Les tests peuvent être ignorés par les indicateurs ci-dessous:

  • -DskipTests ignore les tests unitaires et d'intégration
  • -DskipUnitTests ignore les tests unitaires mais exécute les tests d'intégration
  • -DskipIntegrationTests ignore les tests d'intégration mais exécute les tests unitaires

Exécution de tests

Exécutez ci-dessous pour exécuter uniquement des tests unitaires

mvn clean test

Vous pouvez exécuter la commande ci-dessous pour exécuter les tests (à la fois unité et intégration)

mvn clean verify

Afin d'exécuter uniquement les tests d'intégration, suivez

mvn failsafe:integration-test

Ou sauter les tests unitaires

mvn clean install -DskipUnitTests

Aussi, pour sauter les tests d'intégration pendant mvn install, suivez

mvn clean install -DskipIntegrationTests

Vous pouvez ignorer tous les tests en utilisant

mvn clean install -DskipTests
Liquidpie
la source