web-dev-qa-db-fra.com

Comment puis-je ignorer les tests dans Maven Install Goal, tout en les exécutant dans Maven Test Goal?

J'ai un projet multi-module Maven avec des tests d'intégration et unitaires dans le même dossier (src/test/Java). Les tests d'intégration sont marqués de @Category(IntegrationTest.class). Je veux finir avec la configuration suivante:

  1. Si je cours mvn install, Je veux que tous les tests soient compilés, mais je ne veux en exécuter aucun.
  2. Si je cours mvn test, Je veux que tous les tests soient compilés, mais n'exécutent que des tests unitaires.
  3. Si je cours mvn integration-test, Je veux compiler et exécuter tous les tests.

Le point important est que je veux que ce soit configuré dans le pom.xml sans arguments de ligne de commande supplémentaires.

Actuellement, je suis arrivé avec la configuration suivante dans mon parent pom.xml, où le seul problème est # 1, où tous les tests sont exécutés:

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${project.Java.version}</source>
                    <target>${project.Java.version}</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.14.1</version>
                <dependencies>
                    <dependency>
                        <groupId>org.Apache.maven.surefire</groupId>
                        <artifactId>surefire-junit47</artifactId>
                        <version>2.14.1</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <includes>
                        <include>**/*.class</include>
                    </includes>
                    <excludedGroups>cz.cuni.xrg.intlib.commons.IntegrationTest</excludedGroups>
                </configuration>
            </plugin>

            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.14.1</version>
                <dependencies>
                    <dependency>
                        <groupId>org.Apache.maven.surefire</groupId>
                        <artifactId>surefire-junit47</artifactId>
                        <version>2.14.1</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <groups>cz.cuni.xrg.intlib.commons.IntegrationTest</groups>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                        <configuration>
                            <includes>
                                <include>**/*.class</include>
                            </includes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

Tous les modules enfants ont la configuration de plug-in suivante dans leur pom.xml, qui, à mon avis, devrait hériter du pom parent:

<build> 
    <plugins>
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
        </plugin>

        <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
        </plugin>
    </plugins>
</build>

J'ai essayé d'utiliser <skipTests>true</skipTests>, mais cela désactive l'exécution du test pour tous les objectifs, ce qui n'est pas ce que je veux (enfreint les n ° 2 et n ° 3). C’est aussi assez étrange, que mvn test honore le skipTests=true option ... pourquoi voudrais-je l'exécuter en premier lieu ??

Après des heures passées à googler et à essayer différentes combinaisons, j'hésite à savoir s'il est même possible de ne pas exécuter de tests dans mvn install, tout en les exécutant dans mvn test. J'espère que quelqu'un prouve ce qui ne va pas. ;)

Je suis également disposé à accepter une solution, où mvn install n'exécuterait que des tests unitaires, mais je ne pense pas que cela fasse une grande différence.

55
thegeko

On dirait que vous n'avez pas compris le concept de build-cycle de vie dans Maven. Si vous exécutez mvn install toutes les phases du cycle de vie (y compris la phase install lui-même) sont exécutées avant la phase d’installation. Cela signifie exécuter les phases suivantes:

  1. valider
  2. initialiser
  3. générer des sources
  4. sources de processus
  5. générer des ressources
  6. processus-ressources
  7. compiler
  8. classes de processus
  9. générer-test-sources
  10. processus-test-sources
  11. générer des ressources de test
  12. processus-test-ressources
  13. test-compiler
  14. processus-test-classes
  15. tester
  16. préparer-paquet
  17. paquet
  18. pré-test d'intégration
  19. test d'intégration
  20. test post-intégration
  21. vérifier
  22. installer

ce qui signifie en d'autres termes le test ainsi que le integration-test les phases du cycle de vie sont incluses. Donc, sans aucune information supplémentaire, il n'est pas possible de changer le comportement comme vous le souhaitez.

Pour ce faire, utilisez un profil dans Maven:

 <project>
  [...]
  <profiles>
    <profile>
      <id>no-unit-tests</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
              <skipTests>true</skipTests>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
  [...]
</project>

Donc, votre première exigence:

  1. Si je cours mvn install, Je veux que tous les tests soient compilés, mais je ne veux en exécuter aucun.

peut être atteint en utilisant ce qui suit:

mvn -Pno-unit-test test
  1. Si je cours mvn test, Je veux que tous les tests soient compilés, mais n'exécutent que des tests unitaires.

Ceci peut simplement être réalisé en utilisant l’appel simple:

mvn test

car la phase des tests d'intégration n'est pas exécutée (voir le cycle de vie de la construction).

  1. Si je cours mvn integration-test, Je veux compiler et exécuter tous les tests.

Cela signifie exécuter la valeur par défaut, qui inclut la phase test qui exécutera les tests unitaires (maven-surefire-plugin) et le test d’intégration géré par le plugin maven-failafe. Mais vous devez savoir que si vous souhaitez appeler les tests d'intégration, vous devez utiliser la commande suivante:

mvn verify

à la place, parce que vous avez manqué le post-integration-test phase dans votre appel précédent.

Outre ce qui précède, vous devez suivre les conventions de dénomination pour les tests unitaires et les tests d'intégration où tests unitaires doit être nommé comme suit:

<includes>
 <include>**/*Test*.Java</include>
 <include>**/*Test.Java</include>
 <include>**/*TestCase.Java</include>
</includes>

et tests d'intégration doivent être nommés comme suit:

<includes>
 <include>**/IT*.Java</include>
 <include>**/*IT.Java</include>
 <include>**/*ITCase.Java</include>
</includes>

J'espère que vous avez configuré le plug-in maven-fail-safe comme suit, qui est nécessaire pour lier le plug-in maven-fail-safe aux phases de cycle de vie correctes:

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.Apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>2.15</version>
        <executions>
          <execution>
            <goals>
              <goal>integration-test</goal>
              <goal>verify</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

comme vous l'avez fait correctement, mais vous devez savoir que les balises include fonctionnent sur le code source (. Java) et non sur les noms compilés (.classe). Je n'utiliserais pas l'annotation Catégorie, mais simplement l'utilisation des conventions de dénomination rend le pom plus simple et plus court.

91
khmarbaise

Selon le documentation du plug-in Failsafe

mvn install -DskipITs

c'est ce que tu veux.

49
gli00001

Quel OP a déclaré dans sa question:

Si je lance mvn install, je veux que tous les tests soient compilés, mais je ne veux pas en exécuter.
Si je lance test mvn, je veux que tous les tests soient compilés, mais que seuls les tests unitaires soient exécutés.
Si je lance mvn integration-test, je veux compiler et exécuter tous les tests.

est parfaitement valide et extrêmement facile à réaliser.
EDIT: sauf première condition, qui agit contre la nature maven. Le meilleur moyen ici serait simplement de faire mvn install -DskipTests

Tout ce dont vous avez besoin est de suivre l'extrait dans pom.xml:

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.17</version>
    <executions>
        <execution>
            <id>integration-tests</id>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
</plugin>

et de s'en tenir aux conventions de nommage maven pour les tests unitaires et d'intégration (comme @khmarbaise l'a déjà indiqué). Ainsi, nommez généralement vos tests d'intégration avec le suffixe IT (par exemple MyIntegrationTestIT.Java) Et laissez maven-failsafe Faire son travail.
De cette façon, vous n’avez même pas besoin des catégories JUnit (bien qu’elles puissent parfois être très utiles).

C'est ça :)

  • mvn test Exécute niquement tests unitaires
  • mvn integration-test Exécute tous les tests
  • mvn failsafe:integration-test Fonctionne niquement tests d'intégration
  • mvn clean verify Pour être sûr que tout le projet fonctionne


Quelques conseils personnels

Le fait de conserver les tests d'intégration séparément des tests unitaires vous permet de facilement exécuter votre IDE tous les tests de certains packages. Un répertoire supplémentaire appelé test-integration (Ou integrationtest) est généralement utilisé. dans ce but.
C’est aussi facile à réaliser avec maven:

<plugin>
    <!-- adding second test source directory (just for integration tests) -->
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>1.9.1</version>
    <executions>
        <execution>
            <id>add-integration-test-source</id>
            <phase>generate-test-sources</phase>
            <goals>
                <goal>add-test-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>src/test-integration/Java</source>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>

Et déplacez ensuite vos tests d'intégration dans ce répertoire. Cela devrait ressembler à:

src
   main
   test
   test-integration

Les tests d'intégration nécessitent généralement plus de mémoire:

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    ...
    <configuration>
        <argLine>-Xmx512m -XX:MaxPermSize=256m</argLine>
    </configuration>
</plugin>
16
G. Demecki

Cet article explique comment ignorer les tests d'intégration, quel que soit le plug-in que vous utilisez pour ces tests.

Fondamentalement, vous définissez un profil et placez tout le code xml lié à vos tests d'intégration dans ce profil. Que vous l'activiez quand une propriété -DskipIntegrationTests est manquant.

Vous pouvez faire la même chose pour les tests unitaires: écrivez un profil et activez-le quand -DskipUnitTests est manquant.

Ensuite, vous pourriez faire:

mvn install -DskipIntegrationTests -DskipUnitTests # (runs install without any tests)
mvn test # (runs unit tests)
mvn post-integration-test # (runs all tests)
12
Emil Salageanu

Le maven-failafe-plugin docs a une section intitulée "Saut par défaut".

Malheureusement, les étapes décrites dans cette page ne fonctionnent pas telles quelles. Cependant, un léger changement à ces étapes le fera fonctionner:

Dans la section properties de pom.xml, Ajoute ça:

<skipITs>true</skipITs>

Ajoutez ensuite la propriété skipTests à la section plugin de maven-failafe-plugin:

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <configuration>
        <skipTests>${skipITs}</skipTests>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Alors maintenant, un mvn install _ par défaut exécutera des tests unitaires, mais pas des tests d'intégration.

Mais un mvn install -DskipITs=false exécutera les tests unitaires et les tests d'intégration.

Note de bas de page: Une mauvaise documentation a joué un rôle important dans la raison pour laquelle Maven a été si mal aimé pendant si longtemps.

4
rdguam

mvn test-compile fait exactement ce que vous recherchez. Vous pouvez simplement remplacer mvn install avec mvn test-compile et vous avez terminé. Pas besoin de personnaliser le fichier pom ou quoi que ce soit. La question liée ci-dessous est similaire autour de # 1:

Maven - Comment compiler des tests sans les exécuter?

mvn test-compile devrait être acceptée comme la meilleure réponse, car Maven prend en charge exactement ce que vous voulez faire de manière native et sans aucune magie. Vous vous retrouveriez avec ceci:

If I run mvn test-compile, I want all tests to compile, but I do not want to execute any.
If I run mvn test, I want all tests to compile, but execute only unit tests.
If I run mvn integration-test, I want to compile and execute all tests.
2
Ferg

Ne spécifiez pas les étapes d'exécution dans la configuration du plug-in de sécurité. Par exemple.

    <plugins>
        <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.0.0-M3</version>
        </plugin>
    </plugins>

Maintenant, vous devez spécifiquement appeler mvn failafe: integration-test pour exécuter les tests d'intégration; ils seront ignorés dans d'autres cibles MVN.

0
guymac