Comment puis-je sauter des tests dans maven install goal, tout en les exécutant dans maven test goal?

j'ai un projet Maven multi-modules avec intégration et tests unitaires dans le même dossier (src/test/java). Les essais d'intégration portent la mention @Category(IntegrationTest.class) . Je veux finir avec la configuration suivante:

  1. si j'exécute mvn install , je veux que tous les tests soient compilés, mais je ne veux pas en Exécuter.
  2. si j'exécute 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, je veux que cela configuré dans le pom.xml sans aucun argument de ligne de commande supplémentaire.

Actuellement, je suis venu avec la configuration suivante dans mon pom parent.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 plugin suivante en leur pom.xml, qui je crois devrait hériter de la 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 il désactive l'exécution de test pour tous les buts, ce qui n'est pas ce que je veux (viole #2 et #3). C'est aussi assez étrange, que mvn test honore l'option skipTests=true ...pourquoi voudrais-je l'exécuter en premier lieu??

après des heures de googling et d'essayer différentes combinaisons, j'hésite même s'il est possible de ne pas courir essais en mvn install , tout en les exécutant en mvn test . J'espère que quelqu'un prouve que c'est mal. ;)

je suis également prêt à accepter une solution, où mvn install n'exécuterait que des tests unitaires, mais je ne pense pas que cela fasse beaucoup de différence.

46
demandé sur thegeko 2013-06-15 01:31:29

6 réponses

il semble que vous n'avez pas compris le concept du construire cycle de vie dans Maven. Si vous exécutez mvn install toutes les phases du cycle de vie (y compris la phase install elle-même) exécutez avant la phase d'installation. Cela signifie exécuter les phases suivantes:

  1. valider
  2. initialiser
  3. generate-sources
  4. processus-sources
  5. générer des ressources 1519230920"
  6. processus-ressources
  7. compiler
  8. classes de procédés
  9. generate-test-sources
  10. processus de test-sources
  11. generate-test-ressources
  12. processus de test-ressources
  13. test-compile
  14. processus de test-classes
  15. test
  16. prepare-package
  17. paquet
  18. pre-integration-test
  19. integration-test
  20. post-integration-test
  21. vérifier
  22. installer

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

cela pourrait être réalisé en utilisant 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>

ainsi votre première exigence:

  1. si j'exécute mvn install , je veux que tous les tests soient compilés, mais je ne veux pas en Exécuter.

peut être obtenu en utilisant les éléments suivants:

mvn -Pno-unit-test test
  1. si j'exécute mvn test , je veux que tous les tests soient compilés, mais n'exécuter que des tests unitaires.

cela peut simplement être réalisé en utilisant l'appel simple:

mvn test

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

  1. si j'exécute mvn integration-test , je veux compiler et exécuter tous les tests.

cela signifie exécuter la phase par défaut qui comprend l'exécution de la phase test qui exécutera les essais de l'unité (maven-surefire-plugin) et en outre l'exécution du test d'intégration qui sont gérés par le maven-failsafe-plugin. Mais vous devez être conscient que si vous voulez appeler les tests d'intégration, vous devez utiliser la commande suivante:

mvn verify

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

en dehors de ce qui précède, vous devez suivre les conventions de nommage pour les tests unitaires et 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 les" essais 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 maven-failsafe-plugin comme suit qui est nécessaire pour lier le maven-failsafe-plugin à la correcte phases du cycle de vie:

<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 le include tags travaille sur le code source ( .java) et non sur les noms compilés ( .classe.) Je n'utiliserais pas l'annotation de catégorie, simplement en utilisant les conventions de nommage rend le pom plus simple et plus court.

83
répondu khmarbaise 2018-03-15 12:16:18

selon le documentation du Plugin Failsafe

mvn install -DskipITs

est ce que vous voulez.

40
répondu gli00001 2016-02-23 11:20:59

Ce que l'OP a déclaré, dans sa question:

si j'exécute mvn install , je veux que tous les tests soient compilés, mais je ne veux pas pour en exécuter une.

Si j'exécute mvn test , je veux que tous les tests soient compilés, mais n'exécutent que des tests unitaires.

Si j'exécute mvn integration-test , je veux compiler et exécuter tous les tests.

est parfaitement valide et extrêmement facile à réaliser.

EDIT: excepté la première condition, qui agit contre la nature maven. La meilleure façon ici serait tout simplement de faire mvn install -DskipTests

Tout ce dont vous avez besoin est l'extrait suivant 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 Maven naming conventions pour les tests d'unité et d'intégration (as @khmarbaise déjà dit). 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 de catégories JUnit (même si parfois elles peuvent être très utiles).

:)

  • mvn test exécute seulement tests unitaires
  • mvn integration-test exécute tous les tests
  • mvn failsafe:integration-test runs seulement les tests d'intégration
  • mvn clean verify quand on veut être sûr, tout le projet fonctionne



quelques conseils personnels

le fait de séparer les tests d'intégration des tests unitaires vous permet d'exécuter facilement dans votre IDE tous les tests d'un paquet. Généralement répertoire supplémentaire appelé test-integration (ou integrationtest ) est utilisé à cette fin.

Cela est également 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 ensuite déplacer vos tests d'intégration dans ce répertoire. Il 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>
15
répondu G. Demecki 2017-12-21 09:37:14

Ce post explique comment ignorer les tests d'intégration, n'importe quel plugin que vous utilisez pour ces tests.

fondamentalement, ce que vous faites est de définir un profil et mettre tout votre code xml lié à des tests d'intégration à l'intérieur de ce profil. Que vous l'activez quand un bien -DskipIntegrationTests est manquant.

vous pouvez faire la même chose pour les tests unitaires: écrire un profil et l'activer quand -DskipUnitTests est manquant.

alors, 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
répondu Emil Salageanu 2018-08-16 16:21:36

le maven-failsafe-plugin docs a une section intitulée" sauter par défaut."

malheureusement, les étapes décrites dans cette page ne fonctionnent pas comme elles sont écrites. Toutefois, un léger changement à ces étapes fera en sorte que cela fonctionne:

dans la section properties de pom.xml , ajouter ce qui suit:

<skipITs>true</skipITs>

ensuite, ajouter le bien skipTests à la section plugin du maven-failsafe-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>

donc 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 à la fois des tests unitaires et des tests d'intégration.

note de bas de page: une mauvaise documentation a joué un grand rôle sur la raison pour laquelle Maven a été si mal aimé pendant si longtemps.

4
répondu rdguam 2017-02-22 19:30:08

mvn test-compile fait exactement ce que vous cherchez. Vous pouvez simplement remplacer mvn install par 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 soutient exactement ce que vous voulez faire nativement et sans aucune magie. Vous finiriez 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
répondu Ferg 2017-06-20 14:40:35