Comment puis-je ignorer les tests dans l’objective d’installation de maven, tout en les exécutant dans un objective de test Maven?

J’ai un projet multi-modules maven avec à la fois des tests d’intégration et des tests unitaires dans le même dossier (src / test / java). Les tests d’intégration sont marqués avec @Category(IntegrationTest.class) . Je veux me retrouver avec la configuration suivante:

  1. Si je lance mvn install , je souhaite que tous les tests soient compilés, mais je ne veux en exécuter aucun.
  2. Si je mvn test , je souhaite que tous les tests soient compilés, mais n’exécutent que des tests unitaires.
  3. Si je lance le mvn integration-test , je veux comstackr et exécuter tous les tests.

Le point important est que je veux que cela soit configuré dans le pom.xml sans aucun argument de ligne de commande supplémentaire.

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

     org.apache.maven.plugins maven-comstackr-plugin  ${project.java.version} ${project.java.version}    org.apache.maven.plugins maven-surefire-plugin 2.14.1   org.apache.maven.surefire surefire-junit47 2.14.1     **/*.class  cz.cuni.xrg.intlib.commons.IntegrationTest    maven-failsafe-plugin 2.14.1   org.apache.maven.surefire surefire-junit47 2.14.1    cz.cuni.xrg.intlib.commons.IntegrationTest     integration-test verify    **/*.class         

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

    org.apache.maven.plugins maven-surefire-plugin   maven-failsafe-plugin    

J’ai essayé d’utiliser true , mais cela désactive l’exécution des tests pour tous les objectives, ce qui n’est pas ce que je veux (viole les numéros 2 et 3). Il est également assez étrange que mvn test honore l’option skipTests=true … pourquoi voudrais-je le lancer en premier lieu ??

Après des heures de googler et d’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 mvn test en même temps dans mvn test . J’espère que quelqu’un prouve que c’est faux. 😉

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.

On dirait que vous n’avez pas compris le concept du cycle de vie de la construction dans Maven. Si vous exécutez mvn install toutes les phases du cycle de vie (y compris la phase d’ install proprement mvn install ) 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. ressources de processus
  7. comstackr
  8. classes de processus
  9. générer des sources de test
  10. sources de test de processus
  11. générer des ressources de test
  12. ressources de test de processus
  13. comstackr les tests
  14. classes de test de processus
  15. tester
  16. préparer le paquet
  17. paquet
  18. test de pré-intégration
  19. test d’intégration
  20. test post-intégration
  21. Vérifier
  22. installer

ce qui signifie en d’autres termes que les phases du cycle de test , ainsi que du test d’ integration-test sont incluses. Donc, sans informations supplémentaires, il est impossible de modifier le comportement comme vous le souhaitez.

Cela pourrait être réalisé en utilisant un profil dans Maven:

   [...]   no-unit-tests    org.apache.maven.plugins maven-surefire-plugin  true       [...]  

Donc, votre première exigence:

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

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

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

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

 mvn test 

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

  1. Si je lance le mvn integration-test , je veux comstackr et exécuter tous les tests.

Cela signifie qu’il faut exécuter la valeur par défaut qui comprend l’exécution de la phase de test qui exécutera les tests unitaires (maven-surefire-plugin) et exécutera en outre le test d’intégration géré par le plug-in maven-failafe. Mais vous devez savoir que si vous souhaitez appeler les tests d’intégration, vous devez utiliser la commande suivante:

 mvn verify 

au lieu de cela, vous avez manqué la phase de post-integration-test dans votre précédent appel.

En dehors de ce qui précède, vous devez suivre les conventions de dénomination pour les tests unitaires et d’intégration où les tests unitaires doivent être nommés comme suit:

  **/*Test*.java **/*Test.java **/*TestCase.java  

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

  **/IT*.java **/*IT.java **/*ITCase.java  

J’espère que vous avez configuré le plugin maven-failafe-plugin comme suit, qui est nécessaire pour lier le plugin maven-failafe à la bonne phase du cycle de vie:

  [...]    org.apache.maven.plugins maven-failsafe-plugin 2.15    integration-test verify       [...]  

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 ( .class). Je n’utiliserais pas l’annotation Catégorie, simplement en utilisant les conventions de nommage rend le pom plus simple et plus court.

Selon la documentation du plug-in Failsafe

 mvn install -DskipITs 

est ce que tu veux

Ce que OP a déclaré dans sa question:

Si je lance mvn install , je souhaite que tous les tests soient compilés, mais je ne veux en exécuter aucun.
Si je lance le test mvn , je souhaite que tous les tests soient compilés, mais n’exécutent que des tests unitaires.
Si je lance le test d’intégration mvn , je veux comstackr 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 serait simplement d’ mvn install -DskipTests

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

  org.apache.maven.plugins maven-failsafe-plugin 2.17   integration-tests  integration-test verify     

et s’en tenir aux conventions de nommage maven pour les tests unitaires et d’intégration (comme @khmarbaise l’a déjà indiqué). Donc, nommez-vous généralement les 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 (bien que parfois elles puissent être très utiles).

C’est tout 🙂

  • mvn test exécute uniquement des tests unitaires
  • mvn integration-test exécute tous les tests
  • mvn failsafe:integration-test que les tests d’intégration
  • mvn clean verify quand vous voulez être sûr que tout ce projet fonctionne

Quelques conseils personnels

Garder les tests d’intégration séparément des tests unitaires vous permet d’exécuter facilement dans votre IDE tous les tests dans un package. Un répertoire supplémentaire appelé test-integration (ou integrationtest ) est généralement utilisé à cette fin.
Ceci est également facile à réaliser avec maven:

   org.codehaus.mojo build-helper-maven-plugin 1.9.1   add-integration-test-source generate-test-sources  add-test-source    src/test-integration/java      

Et puis déplacez vos tests d’intégration vers 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:

  org.apache.maven.plugins maven-failsafe-plugin ...  -Xmx512m -XX:MaxPermSize=256m   

Cet article explique comment ignorer les tests d’intégration, quel que soit le plugin que vous utilisez pour ces tests.

En gros, vous définissez un profil et placez tout le code XML associé aux tests d’intégration dans ce profil. Ensuite, vous l’activez lorsqu’une propriété -DskipIntegrationTests est manquante.

Vous pouvez faire la même chose pour les tests unitaires: écrivez un profil et activez-le lorsque -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) 

La documentation de maven-failafe-plugin contient une section intitulée “Ignorer par défaut”.

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

Dans la section des properties de pom.xml , ajoutez ceci:

true

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

  org.apache.maven.plugins maven-failsafe-plugin  ${skipITs}     integration-test verify     

Donc, maintenant, une mvn install exécutera par défaut des tests unitaires, mais pas des tests d’intégration.

Mais une mvn install -DskipITs=false exécutera à la fois les tests unitaires et les tests d’intégration.

Note de bas de page: Une mauvaise documentation a joué un rôle important dans le fait que Maven était si détesté depuis si longtemps.

mvn test-comstack fait exactement ce que vous recherchez. Vous pouvez simplement remplacer mvn install avec mvn test-comstack 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 comstackr des tests sans les exécuter?

mvn test-comstack devrait être accepté comme la meilleure réponse car Maven supporte exactement ce que vous voulez faire en mode natif et sans magie. Vous vous retrouveriez avec ceci:

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