2009-12-17 8 views
27

Lorsque vous utilisez cette méthode ci-dessous, configurez jUnit avec Suites. Nous avons eu le problème quand tout @BeforeClass dans chaque Testclass sera exécuté avant que les tests commencent à s'exécuter. (Pour chaque n fichier TestClass, @BeforeClass s'exécute, puis après exécution, il commence à exécuter les premiers fichiers MyTest.class @Test)JUnit 4 @BeforeClass & @AfterClass lors de l'utilisation des suites

Cela entraîne l'allocation de beaucoup de ressources et de mémoire. Je pensais que cela devait être faux, chaque @BeforeClass ne devrait-elle pas être exécutée avant l'exécution de la classe de test, et non lors du démarrage de la suite?

@RunWith(Suite.class) 
@Suite.SuiteClasses({ MyTests.class, Mytests2.class, n1, n2, n }) 
public class AllTests { 
    // empty 
} 


public class MyTests { // no extends here 
    @BeforeClass 
    public static void setUpOnce() throws InterruptedException { 
     ... 
    @Test 
     ... 

public class MyTests2 { // no extends here 
    @BeforeClass 
    public static void setUpOnce() throws InterruptedException { 
     ... 
    @Test 
     ... 
+0

Sont-ils exécutés avant que les tests de chaque classe, ou sont tous exécutés seulement avant la première (mais le second est exécuté sans courir tous @BeforeClass encore)? Ce dernier semble correct car @BeforeClass est exécuté avant les méthodes @Test de ce test. La quantité de mémoire ne changerait pas, à moins que vous ne nettoyiez après les tests de chaque classe (et ceux-ci ne se produisent également qu'une fois la suite complétée). –

+1

Ce que je reçois en ce moment, c'est que chaque @BeforeClass est exécuté en premier. @BeforeClass (Mytests) @BeforeClass (Mytests2) @test (MyTests) @Test (MyTests2) À mon point de vue, ce n'est pas correct. Corrigez-moi si je me trompe, mais quelque chose doit être mal configuré pour causer ce problème. –

Répondre

43

Ecrivez une méthode @BeforeClass dans la classe AllTests qui sera exécutée au démarrage de la suite.

public class MyTests1 { 
    @BeforeClass 
    public static void beforeClass() { 
     System.out.println("MyTests1.beforeClass"); 
    } 

    @Before 
    public void before() { 
     System.out.println("MyTests1.before"); 
    } 

    @AfterClass 
    public static void afterClass() { 
     System.out.println("MyTests1.AfterClass"); 
    } 

    @After 
    public void after() { 
     System.out.println("MyTests1.after"); 
    } 

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

    @Test 
    public void test2() { 
     System.out.println("MyTests1.test2"); 
    } 
} 



public class MyTests2 { 
    @BeforeClass 
    public static void beforeClass() { 
     System.out.println("MyTests2.beforeClass"); 
    } 

    @Before 
    public void before() { 
     System.out.println("MyTests2.before"); 
    } 

    @AfterClass 
    public static void afterClass() { 
     System.out.println("MyTests2.AfterClass"); 
    } 

    @After 
    public void after() { 
     System.out.println("MyTests2.after"); 
    } 

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

    @Test 
    public void test2() { 
     System.out.println("MyTests2.test2"); 
    } 
} 




@RunWith(Suite.class) 
@Suite.SuiteClasses({ MyTests1.class, MyTests2.class }) 
public class AllTests { 

    @BeforeClass 
    public static void beforeClass() { 
     System.out.println("AllTests.beforeClass"); 
    } 

    @Before 
    public void before() { 
     System.out.println("AllTests.before"); 
    } 

    @AfterClass 
    public static void afterClass() { 
     System.out.println("AllTests.AfterClass"); 
    } 

    @After 
    public void after() { 
     System.out.println("AllTests.after"); 
    } 

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

    @Test 
    public void test2() { 
     System.out.println("AllTests.test2"); 
    } 

} 

SORTIE

AllTests.beforeClass 
MyTests1.beforeClass 
MyTests1.before 
MyTests1.test1 
MyTests1.after 
MyTests1.before 
MyTests1.test2 
MyTests1.after 
MyTests1.AfterClass 
MyTests2.beforeClass 
MyTests2.before 
MyTests2.test1 
MyTests2.after 
MyTests2.before 
MyTests2.test2 
MyTests2.after 
MyTests2.AfterClass 
AllTests.AfterClass 

HTH

+4

'AllTests.test1()' et '" AllTests.test2() 'ne sont jamais exécutés? – Theodor

+0

@nayakam Cela résoudrait le problème immédiat, mais je pense que les classes de tests individuels ou subsuites ne peuvent pas être exécutés sur leur posséder? – nsandersen

-4

Je pense que @BeforeClass s'exécute à l'instanciation.

+0

Ce n'est pas le cas. "L'annotation d'une méthode publique vide sans argument avec @BeforeClass provoque son exécution une fois avant l'une des méthodes de test de la classe Les méthodes @BeforeClass des superclasses seront exécutées avant celles de la classe actuelle." (Source: documentation JUnit) – Jorn

+0

Juste ajouter quelques informations supplémentaires pour ceux qui ont des problèmes avec la mémoire. JUnit sauvegardera tous les états lors de l'exécution et sauvegardera donc toutes les variables statiques jusqu'à ce que tous les tests JUnit aient été exécutés. Cela a également été un problème majeur car nous effectuons entre 1000 et 6000 tests JUnit. Cela parce qu'il en a besoin pour afficher le résultat à la fin. –

1

Je ne suis pas trop familier avec @RunWith dans JUnit, donc j'ai peut-être fait quelque chose de mal, mais je n'arrive pas à reproduire le comportement que vous décrivez. Avec la classe:

@RunWith(Suite.class) 
@Suite.SuiteClasses({ FirstTest.class, SecondTest.class, ThirdTest.class }) 
public class AllTests { 
    // empty 
} 

Et FirstTest.java qui ressemble à ceci:

public class FirstTest { 
    @BeforeClass 
    public static void doBeforeClass() { 
     System.out.println("Running @BeforeClass for FirstTest"); 
    } 

    @Test 
    public void doTest() { 
     System.out.println("Running @Test in " + getClass().getName()); 
    } 
} 

... avec SecondTest.java et ThirdTest.java à peu près la même chose. Je reçois la sortie de test:

Running @BeforeClass for FirstTest 
Running @Test in FirstTest 
Running @BeforeClass for SecondTest 
Running @Test in SecondTest 
Running @BeforeClass for ThirdTest 
Running @Test in ThirdTest 

est avec JUnit 4.5.0 (par défaut JUnit dans Eclipse 3.5.1) sur Sun JDK 1.6.0_12. Pouvez-vous repérer une différence dans mon exemple par rapport à la vôtre? Peut-être un JDK/JVM différent? Je ne connais pas assez les internes de JUnit pour savoir si cela peut être un facteur.

+0

Comme vous le décrivez, c'est ce que j'étais censé obtenir aussi. Mais je reçois un tas de @BeforeClass d'abord, puis je vois le premier @Test, @Test et ainsi de suite. En utilisant le JDK 1.6.0_17 de Sun, Eclipse 3.5, mais alors nos tests de Fonction sont exécutés, nous utilisons la commande ant, running maven. Est-ce que cela pourrait affecter les résultats? Si je le configure dans Eclipse et l'exécute, ça marche, il semble que ce problème soit quelque peu dans ant ou maven. –

+0

Désolé, vous ne pouvez vraiment pas vous aider à lancer JUnit dans fourmi ou maven. Bien que j'aie exporté build.xml pour l'exemple que j'ai utilisé, et l'ai exécuté avec la cible des tests, et que j'ai obtenu le comportement que vous recherchez, je doute que tout soit faux avec la tâche JUnit ant. hazzled shrug * – Grundlefleck