84 votes

Avant et Après la Suite de l'exécution de crochet dans jUnit 4.x

Je suis en train de préformation de l'installation et le démontage d'un ensemble de tests d'intégration, en utilisant jUnit 4.4 pour exécuter les tests. Le démontage doit être exécuté de manière fiable. Je vais avoir d'autres problèmes avec TestNG, donc je suis à la recherche de port de retour de jUnit. Ce que les crochets sont disponibles pour l'exécution avant tout les tests sont exécutés et après tous les tests sont terminés?

Remarque: nous sommes à l'aide de maven 2 pour notre build. J'ai essayé d'utiliser maven de l' pre- & post-integration-test phases, mais, si un test échoue, maven s'arrête et ne pas exécuter post-integration-test, ce qui n'aide pas.

117voto

Julie Points 3850

Oui, il est possible de manière fiable exécuter le montage et le démontage des méthodes d'avant et d'après tous les tests dans une suite de tests. Permettez-moi de démontrer dans le code:

package com.test;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({Test1.class, Test2.class})
public class TestSuite {

    @BeforeClass
    public static void setUp() {
    	System.out.println("setting up");
    }

    @AfterClass
    public static void tearDown() {
    	System.out.println("tearing down");
    }

}

Si votre classe Test1 ressemblerait à quelque chose comme:

package com.test;

import org.junit.Test;


public class Test1 {
    @Test
    public void test1() {
    	System.out.println("test1");
    }

}

...et vous pouvez imaginer que Test2 ressemble. Si vous avez exécuté TestSuite, vous obtenez:

setting up
test1
test2
tearing down

Donc vous pouvez voir que la mise en place/démonter seulement exécuter avant et après tous les tests, respectivement.

Le hic: cela ne fonctionne que si vous êtes en cours d'exécution de la suite de test, ne pas courir Test1 et Test2 individuels JUnit tests. Vous avez mentionné que vous utilisez maven, et le maven plugin surefire aime exécuter les tests individuellement, et ne fait pas partie d'une suite. Dans ce cas, je recommande la création d'une super-classe, chaque classe de test s'étend. La super-classe contient alors le annotée @BeforeClass et @AfterClass méthodes. Bien que pas aussi propre que la méthode ci-dessus, je pense qu'il va travailler pour vous.

Comme pour le problème de l'échec des tests, vous pouvez configurer maven.test.erreur.ignorez donc que la construction se poursuit sur l'échec des tests. Ce n'est pas recommandé comme une pratique continue, mais il devrait vous permettre de fonctionner jusqu'à ce que l'ensemble de vos tests passent. Pour plus de détails, voir le maven infaillible de la documentation.

37voto

Martin Vysny Points 559

Un de mes collègues m'a suggéré ce qui suit: vous pouvez utiliser un personnalisé RunListener et de mettre en œuvre la testRunFinished() la méthode: http://junit.sourceforge.net/javadoc/org/junit/runner/notification/RunListener.html#testRunFinished(org.junit.runner.Result)

Pour enregistrer le RunListener il suffit de configurer le plugin surefire comme suit: http://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.html la section "Utilisation des modules d'écoute personnalisés et les journalistes"

Cette configuration doit aussi être choisi par le failsafe plugin. Cette solution est génial parce que vous n'avez pas à spécifier les Suites, la recherche de classes de test ou de l'une de ces trucs - il vous permet de Maven pour faire sa magie, en attente pour tous les tests à la fin.

12voto

ArtB Points 3922

5voto

Jroc Points 360

À l'aide d'annotations, vous pouvez faire quelque chose comme ceci:

import org.junit.*;
import static org.junit.Assert.*;
import java.util.*;

class SomethingUnitTest {
    @BeforeClass
    public static void runBeforeClass()
    {

    }

    @AfterClass
    public static void runAfterClass()
    {  

    }

    @Before  
    public void setUp()
    {

    }

    @After
    public void tearDown()
    {

    }

    @Test
    public void testSomethingOrOther()
    {

    }

}

2voto

christophe blin Points 51

À condition que tous vos tests peuvent s'étendre d'une "technique" de la classe et sont dans le même paquet, vous pouvez faire un petit truc :

public class AbstractTest {
  private static int nbTests = listClassesIn(<package>).size();
  private static int curTest = 0;

  @BeforeClass
  public static void incCurTest() { curTest++; }

  @AfterClass
  public static void closeTestSuite() {
      if (curTest == nbTests) { /*cleaning*/ }             
  }
}

public class Test1 extends AbstractTest {
   @Test
   public void check() {}
}
public class Test2 extends AbstractTest {
   @Test
   public void check() {}
}

Sachez que cette solution a beaucoup d'inconvénients :

  • doit exécuter tous les tests de l'emballage
  • doit sous-classe d'une "technique" de la classe
  • vous ne pouvez pas utiliser @BeforeClass et @AfterClass à l'intérieur des sous-classes
  • si vous exécutez un seul test dans l'emballage, le nettoyage n'est pas fait
  • ...

Pour plus d'informations: listClassesIn() => Comment trouvez-vous toutes les sous-classes d'une classe donnée en Java?

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