2011-11-28 17 views
6

C'è un modo per sapere in una classe di test JUnit 4, se la classe è stata avviata da una Test-Suite? Ho cose globali che voglio eseguire prima di tutti i test (per quanto riguarda il DB in memoria), quindi ho pensato di farlo nel test-suit. Tuttavia, voglio ancora essere in grado di avviare un test alla volta senza un Test-Suit, quindi ho bisogno di sapere se ho bisogno di inizializzare le cose globali nella parte @Before del test ... Qualcuno sa se è possibile ?Invocazione test: come eseguire l'impostazione comune a tutte le suite di test

risposta

5

Ci sono diversi modi per raggiungere questo obiettivo. Il modo più semplice e semplice è avere un 'test' che viene eseguito all'inizio e alla fine della suite che imposta il tuo database e quindi imposta una bandiera globale. Nei test @Before e @After si controlla questo flag e, se necessario, si esegue il setup/teardown.

@RunWith(Suite.class) 
@SuiteClasses({SetupTest.class, RealTest.class, TeardownTest.class}); 

Questa è la soluzione più semplice, ma non è molto bello, quindi una soluzione più ordinato sarebbe quella di utilizzare un TestRule. Guarda estendere ExternalResource. Questo implementa prima dello & dopo la logica che circonda i metodi di test. Ciò ti consentirebbe di calcolare i metodi @Before e @After, per riutilizzare lo stesso codice ovunque.

Quindi, per la suite, è necessario implementare anche la logica prima/dopo. Sfortunatamente, la classe annotata con @RunWith (Suite.class) non è in realtà un'istanza, quindi non è possibile utilizzare il costruttore di quella classe, ma è possibile estendere Suite. A seconda di come verrà eseguito questo, sarà necessario implementare uno dei costruttori, utilizzando @RunWith come esempio:

public class MySuite extends Suite { 
    /** 
    * Called reflectively on classes annotated with <code>@RunWith(Suite.class)</code> 
    * 
    * @param klass the root class 
    * @param builder builds runners for classes in the suite 
    * @throws InitializationError 
    */ 
    public MySuite(Class<?> klass, RunnerBuilder builder) throws InitializationError { 
     this(builder, klass, getAnnotatedClasses(klass)); 
     // put your global setup here 
     // set global variable 
    } 
} 

quindi eseguire il test suite con

@RunWith(MySuite.class) 

Ci sono diversi costruttori che vengono utilizzati in situazioni diverse, guarda i commenti accanto a ciascuno per le specifiche. È ancora necessario utilizzare una variabile globale in modo che le regole non rieseguano il codice di configurazione. Quanto sopra funzionerà se si desidera eseguire solo il codice di configurazione, l'esecuzione del codice di rimozione è più difficile, ma può essere eseguita. Fammi sapere se ne hai bisogno :-)

Se desideri maggiore flessibilità (ad esempio l'esecuzione del codice di configurazione solo per metodi specifici), consulta la risposta allo How to define JUnit method rule in a suite?.

+0

La maggior parte dei link sono morti. – Nadar

2

Vorrei utilizzare le annotazioni JUnit @BeforeClass e @AfterClass per indicare i metodi per eseguire questo tipo di lavoro.

Dal Javadoc @BeforeClass:

A volte diversi test hanno bisogno di condividere computazionalmente costoso configurazione (come la registrazione in un database). Mentre questo può compromettere l'indipendenza dei test da , a volte è un'ottimizzazione necessaria. Annotando un metodo no-arg statico pubblico vuoto con @BeforeClass, è necessario eseguire una volta prima di uno qualsiasi dei metodi di test nella classe. I metodi @BeforeClass di superclassi verranno eseguiti prima di quelli della classe corrente .

+1

Questo è rilevante per diversi metodi @Test annotati all'interno di un file di classe di test, che non è lo scenario con cui ho a che fare, ne ho bisogno per diverse CLASSI di test. – stdcall

0

È possibile inserire del codice @BeforeClass in ciascuna suite di test, che delega a una classe ausiliaria che esegue la configurazione comune. La classe ausiliaria potrebbe avere un static boolean che registra se la configurazione è già stata eseguita. Se è già stato fatto, la classe ausiliaria non farebbe nulla.

Problemi correlati