2009-12-17 6 views
27

Wenn Sie diesen Ansatz unten verwenden, richten Sie das jUnit mit Suites ein. Wir haben das Problem, wenn alle @BeforeClass in jeder Testklasse ausgeführt werden, bevor Tests gestartet werden. (Für jede n TestClass-Datei wird die @BeforeClass ausgeführt, danach werden die ersten MyTest.class-Dateien gestartet @Test)JUnit 4 @BeforeClass & @AfterClass bei Verwendung von Suites

Dies wird dazu führen, dass wir viel Ressourcen und Arbeitsspeicher zuweisen. Meine Gedanken waren, dass es falsch sein muss, sollte nicht jede @BeforeClass nur ausgeführt werden, bevor die eigentliche Testklasse ausgeführt wird, nicht wenn die Suite gestartet wird?

@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

Sind sie vor jeder Klassen die Tests ausgeführt werden, oder alle ausgeführt werden, nur vor dem ersten (aber dann wird der zweite Lauf ohne alle @BeforeClass laufen nochmal)? Letzteres scheint in Ordnung zu sein, da @BeforeClass vor den @ Test-Methoden in diesem Test ausgeführt wird. Die Menge an Speicher würde ich nicht ändern, nehme ich an, es sei denn, Sie bereinigen nach jeder Klasse Tests (und diese sind auch nur, nachdem die gesamte Suite abgeschlossen ist). –

+1

Was ich jetzt bekomme ist, dass jede @BeforeClass zuerst ausgeführt wird. @BeforeClass (MyTests) @BeforeClass (Mytests2) @Test (MyTests) @Test (MyTests2) Zu meiner Sicht ist dies nicht korrekt. Korrigieren Sie mich, wenn ich falsch liege, aber etwas muss falsch eingerichtet sein, um dieses Problem zu verursachen. –

Antwort

43

Schreiben Sie eine @BeforeClass-Methode in die AllTests-Klasse, die ausgeführt wird, wenn die Suite gestartet wird.

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"); 
    } 

} 

OUTPUT

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()' und '" AllTests.test2() 'werden nie ausgeführt? – Theodor

+0

@nayakam Das würde das unmittelbare Problem lösen, aber ich denke dann können die einzelnen Tests Klassen oder Subsuites nicht auf ihren laufen besitzen? – nsandersen

-4

Ich denke, führt @BeforeClass bei Instanciation.

+0

Es tut es nicht. "Die Annotation einer öffentlichen statischen void no-arg-Methode mit @BeforeClass bewirkt, dass sie einmal vor einer der Testmethoden in der Klasse ausgeführt wird. Die @BeforeClass-Methoden der Superklassen werden vor denen der aktuellen Klasse ausgeführt." (Quelle: JUnit Dokumentation) – Jorn

+0

Ich werde nur einige zusätzliche Informationen für diejenigen hinzufügen, die Probleme mit dem Speicher haben. JUnit speichert alle Zustände beim Ausführen und speichert daher auch alle statischen Variablen, bis alle JUnit-Tests ausgeführt wurden. Dies war auch ein großes Problem, da wir zwischen 1000-6000 JUnit Tests laufen. Dies, weil es benötigt wird, um das Ergebnis am Ende anzuzeigen. –

1

Ich bin nicht vertraut mit @RunWith in JUnit, also habe ich etwas falsch gemacht, aber ich kann nicht scheinen, das Verhalten zu replizieren, das Sie beschreiben. Mit der Klasse:

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

Und FirstTest.java suchen wie folgt aus:

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()); 
    } 
} 

... mit SecondTest.java und ThirdTest.java so ziemlich das gleiche. Ich erhalte die Testausgabe:

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

Dies ist mit JUnit 4.5.0 (Standard JUnit in Eclipse 3.5.1) auf Sun JDK 1.6.0_12. Kannst du irgendeinen Unterschied in meinem Beispiel von deinem unterscheiden? Vielleicht ein anderes JDK/JVM? Ich weiß nicht genug über die Interna von JUnit, um zu wissen, ob diese ein Faktor sein können.

+0

Wie du beschreibst, ist das was ich auch bekommen soll. Aber ich bekomme zuerst einen Haufen @BeforeClass, dann sehe ich den ersten @Test, @Test und so weiter. Mit Suns JDK 1.6.0_17, Eclipse 3.5, aber dann werden unsere Funktionstests ausgeführt. Wir verwenden ant, running maven. Könnte etwas davon die Ergebnisse beeinflussen? Wenn ich es in Eclipse und starten Sie es funktioniert, scheint es, dass dieses Problem etwas in ameise oder maven ist. –

+0

Sorry, kann dir wirklich nicht helfen mit JUnit in Ameise oder Maven laufen. Obwohl ich build.xml für das Beispiel, das ich verwendet habe, exportiert habe und es mit dem Testziel ausgeführt habe und das von Ihnen gesuchte Verhalten erhalten habe, bezweifle ich, dass mit der JUnit ant-Aufgabe etwas nicht stimmt. * rätselhafte Achselzucken * – Grundlefleck

Verwandte Themen