web-dev-qa-db-fra.com

Meilleures pratiques pour les tests d'intégration avec Maven?

J'ai un projet que je construis avec Maven qui utilise Hibernate (et Spring) pour récupérer les données d'une base de données, etc.

Mes "tests" pour les DAO de mon projet étendent AbstractTransactionalDataSourceSpringContextTests de Spring afin qu'un DataSource puisse être câblé dans ma classe en cours de test pour pouvoir réellement exécuter la logique de requête/mise en veille prolongée, pour récupérer des données, etc.

Sur plusieurs autres projets, j'ai utilisé ces types de test de concert avec une base de données HSQL (en mémoire ou pointée vers un fichier) pour pouvoir tester efficacement la logique d'interrogation de la base de données réelle sans compter sur une base de données externe. Cela fonctionne très bien, car il évite toute dépendance externe et "l'état" de la base de données avant d'exécuter les tests (dont chacun est encapsulé dans une transaction qui est annulée) est bien défini.

Je suis curieux de savoir quelle est la meilleure façon d'organiser ces tests, qui sont vraiment une saveur lâche des tests d'intégration, avec Maven. C'est un peu sale de garder ces tests dans src/test/Java, mais d'après ce que j'ai lu, il ne semble pas y avoir de stratégie ou de pratique cohérente pour organiser des tests d'intégration avec Maven.

D'après ce que j'ai lu jusqu'à présent, il semble que je puisse utiliser le plugin Failsafe (ou une deuxième instance de Surefire) et le lier au integration-test phase, et que je peux également lier une logique de démarrage ou d'arrêt personnalisée (comme pour démarrer/arrêter l'instance HSQL) à pre-integration-test ou post-integration-test. Mais est-ce vraiment la meilleure méthode?

Ma question est donc la suivante: quelle est la meilleure pratique généralement acceptée pour organiser cela avec Maven? J'ai du mal à trouver une sorte de réponse cohérente dans la documentation.

Ce que j'aimerais, c'est:

  • Séparez les tests unitaires des tests d'intégration, donc seuls les tests unitaires sont exécutés pendant la phase test
  • La possibilité de lier une logique de démarrage/arrêt personnalisée à pre-integration-test et post-integration-test
  • Faire fusionner/présenter les rapports des tests d'intégration avec les rapports de test unitaire Surefire
68
matt b

Il y a ceci page codehaus avec quelques directives. J'ai trouvé le plugin à sécurité intégrée un peu un hack, et cela rend l'exécution des tests unitaires dans Eclipse incroyablement compliquée. Je fais largement ce que vous décrivez.

Définir les tests d'intégration dans src/itest/Java Dans la phase de pré-test d'intégration:

  • Effacer les classes cibles/tests
  • Utilisez le but de add-test-source de build-helper-maven-plugin pour ajouter l'emplacement de la source itest
  • Utilisez un Mojo personnalisé pour supprimer src/test/Java de la configuration afin que les tests unitaires ne soient pas compilés à nouveau (je n'aime pas vraiment cela, mais il est nécessaire de maintenir la séparation des tests unitaires et d'intégration).
  • Utilisez le plugin-compilateur pour compiler les tests d'intégration

Ensuite, dans la phase de test d'intégration, utilisez le plugin surefire pour exécuter les tests.

Enfin, associez tous les objectifs de rangement à la phase de post-test d'intégration (bien qu'ils ne soient normalement pas nécessaires car vous pouvez utiliser le démontage de test () pour ranger).

Je n'ai pas encore trouvé de moyen de fusionner les résultats des tests au fur et à mesure que la phase de rapport est terminée, mais j'ai tendance à voir les tests d'intégration comme un bonus supplémentaire, donc tant qu'ils réussissent, le rapport n'est pas si important.

Mise à jour: Je pense qu'il vaut la peine de souligner que vous pouvez exécuter Jetty à partir de vos tests d'intégration plutôt que d'utiliser un objectif Jetty. Cela vous donne un contrôle beaucoup plus fin sur les tests. Vous pouvez obtenir plus de détails sur cette réponse et les blogs référencés.

21
Rich Seller

Une manière très simple de procéder consiste à utiliser les catégories JUnit.

Vous pouvez ensuite facilement exécuter certains tests pendant la phase de test et un autre pendant la phase de test d'intégration.

Cela prend quelques minutes et ne nécessite que 3 étapes.

  1. Définir une interface de marqueur
  2. Annoter les classes que vous souhaitez diviser
  3. Configurez les plugins Maven.

Un exemple complet est donné ici. https://stackoverflow.com/a/10381662/136538

26
John Dobie

Ce bon article de blog suggère trois options;

1) Module séparé pour les tests d'intégration

2) Différents répertoires sources

3) Différents modèles de nom de fichier

Je n'ai pas encore essayé les trois, donc je ne peux pas donner d'opinion sur ce que je préfère.

7
Mike

Je préfère la deuxième option, Différents répertoires sources, mais j'ai trouvé assez ennuyeux de mettre fin aux tests d'intégration ou d'exclure les packages.

Pour éviter cela, je me suis retrouvé avec cette config:

<properties>
    <testSource>src/test/Java</testSource>
    <testSourceResource>src/test/resources</testSourceResource>
</properties>
<build>
    <testSourceDirectory>${testSource}</testSourceDirectory>
    <testResources>
            <testResource>
            <directory>${testSourceResource}</directory>
            </testResource>
        </testResources>
.....
.....

puis je remplace les deux variables dans des profils différents pour le test d'intégration et d'acceptation:

<profiles>
  <profile>
   <id>acceptance-tests</id>
   <properties>
    <testSource>src/acceptance-test/Java</testSource>
    <testSourceResource>src/acceptance-test/resources</testSourceResource>
   </properties>
  </profile>
 <profile>
   <id>integration-tests</id>
    <properties>
    <testSource>src/integration-test/Java</testSource>
    <testSourceResource>src/integration-test/resources</testSourceResource>
    </properties>
  </profile>
.....
.....
.....
1
Pablo Gutierrez