124 votes

Junit: test d'intégration et tests unitaires

J'ai hérité d'une charge de test Junit, mais ces tests (à l'exception de la plupart ne travaillent pas) sont un mélange de l'unité de test et des tests d'intégration (nécessitant des systèmes externes, db, etc).

Donc, je suis en train de réfléchir à un moyen de les séparer, pour que je puisse exécuter le test de l'unité de nice et rapidement et les tests d'intégration par la suite.

Les options sont..

  1. Les fendre dans des répertoires distincts.

  2. Passer à Junit4 (à partir de v3) et d'annoter les classes pour les séparer.

  3. Utiliser une convention de nommage des fichiers pour dire qu'une classe est , c'est à dire AdapterATest et AdapterAIntergrationTest.

3 a la question qu'Eclipse a l'option "Exécuter tous les tests du projet/de l'emballage ou du dossier". Il serait donc très difficile de simplement exécuter les tests d'intégration.

2: court le risque que les développeurs peuvent commencer à écrire des tests d'intégration dans l'unité de classes de test et il est juste en désordre.

1: Semble être la plus élégante solution, mais mon petit doigt me dit il doit y avoir une meilleure solution.

Voilà donc ma question, comment avez-vous beaucoup de briser les tests d'intégration et de bon tests unitaires?

140voto

John Dobie Points 919

Vous pouvez les séparer très facilement en utilisant JUnit catégories et Maven.

Ceci est montré très, très brièvement ci-dessous par le fractionnement des tests unitaires et d'intégration.

Définir Un Marqueur De L'Interface

La première étape dans le regroupement d'un test à l'aide de catégories est de créer une interface marqueur.

Cette interface sera utilisée pour marquer tous les tests que vous souhaitez exécuter en tant qu'tests d'intégration.

public interface IntegrationTest {}

Marquez vos classes de test

Ajouter la catégorie d'annotation vers le haut de votre classe de test. Elle prend le nom de votre nouvelle interface.

import org.junit.experimental.categories.Category;
@Category(IntegrationTest.class)
public class ExampleIntegrationTest{
  @Test
  public void longRunningServiceTest() throws Exception {
  }
}

Configurer Maven Tests Unitaires

La beauté de cette solution est que rien ne change vraiment pour le test de l'unité côté des choses.

Nous avons simplement ajouter un peu de configuration pour le maven plugin surefire pour se rendre à ignorer les tests d'intégration.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <includes>
      <include>**/*.class</include>
    </includes>
    <excludedGroups>com.test.annotation.type.IntegrationTest</excludedGroups>
  </configuration>
</plugin>

Lorsque vous faites un mvn clean tester votre banalisée tests unitaires d'exécution.

Configurer Maven Tests D'Intégration

De nouveau cette configuration est très simple.

Pour exécuter les tests d'intégration, utilisez ceci:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <groups>com.test.annotation.type.IntegrationTest</groups>
  </configuration>
</plugin>

Si vous mettez cela dans un profil avec l'id IT, vous pouvez exécuter les tests rapides en utilisant mvn clean install. Pour exécuter simplement l'intégration/lent tests, utilisez mvn clean install -P IT.

Mais le plus souvent, vous voulez exécuter les tests rapides par défaut et tous les tests avec -P IT. Si c'est le cas, alors vous devez utiliser un truc:

<profiles>
    <profile>
        <id>IT</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <excludedGroups>java.io.Serializable</excludedGroups> <!-- An empty element doesn't overwrite, so I'm using an interface here which no one will ever use -->
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Comme vous pouvez le voir, je suis à l'exclusion des tests qui sont annotés avec java.io.Serializable. Cela est nécessaire parce que le profil sera hériter de la configuration par défaut du plugin Surefire, de sorte que même si vous dites <excludedGroups/> ou <excludedGroups></excludedGroups>, la valeur com.test.annotation.type.IntegrationTest sera utilisé.

Vous aussi vous ne pouvez pas utiliser none car c'est une interface sur le chemin de la classe (Maven va vérifier cela).

Notes:

  • La dépendance à l' surefire-junit47 n'est nécessaire que lorsque Maven ne pas passer à la JUnit 4 runner automatiquement. À l'aide de l' groups ou excludedGroups élément doit déclencher l'interrupteur. Voir ici.
  • La plupart du code ci-dessus a été prise à partir de la documentation pour le Maven Failsafe plugin. Voir la section "Utilisation de JUnit Catégories" sur cette page.
  • Au cours de mes tests, j'ai trouvé que cela fonctionne même lorsque vous utilisez @RunWith() des annotations pour exécuter des suites de Printemps ou à base de tests.

39voto

lexicore Points 7723

Nous utilisons les Surefire Plugin Maven pour exécuter des tests unitaires et Maven Failsafe Plugin pour exécuter des tests d’intégration. Tests unitaires suivre la naming conventions, tests d’intégration - . C’est donc en fait votre option numéro trois.

Dans quelques projets, nous utilisons TestNG et définir des groupes de tests différents pour les tests d’intégration/unité, mais ce n’est probablement pas approprié pour vous.

12voto

Janusz Points 52607

Je voudrais déplacer jusqu'à Junit4 juste pour l'avoir :)

Vous pouvait les séparer en différentes suites de test. Je ne sais pas comment ils sont organisés en Junit3 mais il devrait être facile de Junit4 juste pour construire des suites de tests et de mettre tous les vrais tests unitaires dans l'un d'eux, puis utiliser une deuxième suite pour les tests d'intégration.

Maintenant définir une configuration d'exécution pour les deux suites dans eclipse et vous pouvez facilement exécuter une unique suite. Ces suites pourrait également être lancé à partir d'un processus automatisé qui permet d'exécuter les tests unitaires à chaque fois que la source de changements et peut-être que les tests d'intégration (si ils sont vraiment gros) qu'une fois par jour ou une fois par heure.

10voto

Steven Mackenzie Points 321

J’utilise actuellement des répertoires séparés en raison de la politique organisationnelle (et l’héritage de Junit 3) mais je n’attends de transition aux annotations moi-même maintenant je suis sur Junit 4.

Je ne serais pas excessivement préoccupé par les développeurs mettant l’intégration des tests dans vos classes de test d’unité - ajouter une règle à vos standards de codage si nécessaire.

Je suis curieux de savoir quelle sorte d’autres solutions, il peut être mis à part les annotations ou séparant physiquement les classes...

6voto

ndp Points 8959

Il n'y a pas une seule bonne réponse. Comme vous l'avez expliqué, il y a plusieurs façons de le faire qui va travailler. Je l'ai fait à la fois le fichier schéma de nommage et le fractionnement des choses dans des répertoires différents.

Il sonne comme le fractionnement chose dans différents répertoires qui pourrait fonctionner mieux pour vous, et qui semble un peu plus clair pour moi, alors je me penche vers l'.

Je ne pense pas que je voudrais essayer annotations parce que cela semble plus fine pour moi. Voulez-vous vraiment ces deux types de tests mélangés dans le même fichier? Je ne le ferais pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X