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:
- si j'exécute
mvn install
, je veux que tous les tests soient compilés, mais je ne veux pas en Exécuter. - si j'exécute
mvn test
, je veux que tous les tests soient compilés, mais n'exécutent que des tests unitaires. - 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.
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:
- valider
- initialiser
- generate-sources
- processus-sources
- générer des ressources 1519230920"
- processus-ressources
- compiler
- classes de procédés
- generate-test-sources
- processus de test-sources
- generate-test-ressources
- processus de test-ressources
- test-compile
- processus de test-classes
- test
- prepare-package
- paquet
- pre-integration-test
- integration-test
- post-integration-test
- vérifier
- 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:
- 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
- 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).
- 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.
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>
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)
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.
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.