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:
mvn install
, Je veux que tous les tests soient compilés, mais je ne veux en exécuter aucun.mvn test
, Je veux que tous les tests soient compilés, mais n'exécutent que des tests unitaires.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.
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:
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:
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
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).
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.
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 unitairesmvn integration-test
Exécute tous les testsmvn failsafe:integration-test
Fonctionne niquement tests d'intégrationmvn clean verify
Pour être sûr que tout le projet fonctionneLe 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>
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)
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.
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.
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.