2009-12-17 13 views
27

Quando si utilizza questo approccio di seguito, configurando jUnit con Suites. Abbiamo il problema quando tutti i @BeforeClass in ogni TestClass verranno eseguiti prima che inizino a essere eseguiti i test. (Per ogni n file TestClass viene eseguito @BeforeClass, dopo aver eseguito, ha iniziato a eseguire i primi file MyTest.class @Test)JUnit 4 @BeforeClass e @AfterClass quando si utilizza Suites

Ciò causerà l'allocazione di molte risorse e memoria. La mia opinione è che deve essere sbagliato, non dovrebbe ogni @BeforeClass eseguire solo prima dell'esecuzione effettiva del testclass, non quando viene avviata 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

Sono essi eseguiti prima prove ciascuno classi, o sono tutti eseguiti solo prima della prima (ma poi il secondo viene eseguito senza eseguire tutte @BeforeClass ancora)? Quest'ultimo aspetto sembra OK poiché @BeforeClass viene eseguito prima dei metodi @Test in tale test. Suppongo che la quantità di memoria non cambierà, a meno che non si pulisca dopo i test di ogni classe (e anche questi si verificano solo dopo aver completato l'intera suite). –

+1

Ciò che ottengo adesso è che ogni @BeforeClass viene eseguito per primo. @BeforeClass (Mytests) @BeforeClass (Mytests2) @Test (MyTests) @Test (MyTests2) A mio punto di vista, questo non è corretto. Correggimi se ho torto, ma qualcosa deve essere impostato in modo errato per causare questo problema. –

risposta

43

Scrivere un metodo @BeforeClass nella classe AllTests che verrà eseguito all'avvio della 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"); 
    } 

} 

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()' e '" AllTests.test2() 'non vengono mai eseguiti? – Theodor

+0

@nayakam Questo risolverebbe il problema immediato, ma penso che le singole classi di test o subsuites non possano essere eseguite sul loro proprio? – nsandersen

-4

credo, @BeforeClass esegue a instanciation.

+0

Non è così. "Annotare un metodo no-arg statico pubblico vuoto con @BeforeClass fa sì che venga eseguito una volta prima di uno qualsiasi dei metodi di test nella classe.I metodi delle superclassi @BeforeClass verranno eseguiti prima di quelli della classe corrente." (Fonte: documentazione JUnit) – Jorn

+0

Aggiungerò semplicemente alcune informazioni aggiuntive per coloro che hanno problemi con la memoria. JUnit salverà tutti gli stati durante l'esecuzione e quindi salverà anche tutte le variabili statiche fino all'esecuzione di tutti i test JUnit. Questo era anche un grosso problema dato che stiamo correndo tra 1000-6000 test JUnit. Questo perché ne ha bisogno per visualizzare il risultato alla fine. –

1

Non ho molta familiarità con @RunWith in JUnit, quindi potrei aver fatto qualcosa di sbagliato, ma non riesco a replicare il comportamento che descrivi. Con la classe:

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

E FirstTest.java simile a questo:

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

... con SecondTest.java e ThirdTest.java praticamente la stessa. Ottengo l'uscita di 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 

Questo è con JUnit (JUnit predefinita in Eclipse 3.5.1) 4.5.0 su Sun JDK 1.6.0_12. Puoi notare qualche differenza nel mio esempio dal tuo? Forse un JDK/JVM diverso? Non ne so abbastanza degli interni di JUnit per sapere se questi possono essere un fattore.

+0

Come descrivi, è ciò che dovrei ottenere anche io. Ma prima ricevo un po 'di @BeforeClass, poi vedo il primo @Test, @Test e così via. Utilizzo di JDK 1.6.0_17 di Sun, Eclipse 3.5, ma successivamente vengono eseguiti i nostri test di funzione che utilizziamo formica, che esegue maven. Qualcuno potrebbe influenzare i risultati? Se lo avessi impostato in Eclipse e lo avvii funziona, sembra che questo problema sia un po 'in formica o in esperto. –

+0

Spiacente, non posso davvero aiutarti con l'esecuzione di JUnit in ant o maven. Anche se ho esportato build.xml per l'esempio che ho usato, e l'ho eseguito con il target dei test, e ho ottenuto il comportamento che stavate cercando, quindi dubito che sia qualcosa di sbagliato nell'attività JUnit Ant. * scrollata di spalle perplessa * – Grundlefleck

Problemi correlati