Raggruppamento di test JUnit

C’è un modo per raggruppare i test in JUnit, in modo da poter eseguire solo alcuni gruppi?

O è ansible annotare alcuni test e quindi disabilitarli globalmente?

Sto usando JUnit 4 , non posso usare TestNG.

modifica: @RunWith e @SuiteClasses funzionano alla grande. Ma è ansible annotare in questo modo solo alcuni test nella class di test? O devo annotare tutta la class di test?

Vuoi raggruppare i test all’interno di una class di test o vuoi raggruppare le classi di test? Ho intenzione di assumere quest’ultimo.

Dipende da come stai facendo i tuoi test. Se li esegui da Maven, è ansible specificare esattamente quali test si desidera includere. Vedi la documentazione di Maven surefire per questo.

Più in generale, però, quello che faccio è che ho un albero di test suite. Una suite di test in JUnit 4 assomiglia a qualcosa:

  @RunWith(Suite.class) @SuiteClasses(SomeUnitTest1.class, SomeUnitTest2.class) public class UnitTestsSuite { } 

Quindi, forse ho un FunctionTestsSuite e un UnitTestsSuite, e poi un AllTestsSuite che include gli altri due. Se li esegui in Eclipse ottieni una bella vista gerarchica.

Il problema con questo approccio è che è un po ‘noioso se si vogliono analizzare i test in più di un modo diverso. Ma è ancora ansible (puoi ad esempio avere un set di suite che si suddividono in base al modulo, poi un altro slicing sul tipo di test).

JUnit 4.8 supporta il raggruppamento:

 public interface SlowTests {} public interface IntegrationTests extends SlowTests {} public interface PerformanceTests extends SlowTests {} 

E poi…

 public class AccountTest { @Test @Category(IntegrationTests.class) public void thisTestWillTakeSomeTime() { ... } @Test @Category(IntegrationTests.class) public void thisTestWillTakeEvenLonger() { ... } @Test public void thisOneIsRealFast() { ... } } 

E infine

 @RunWith(Categories.class) @ExcludeCategory(SlowTests.class) @SuiteClasses( { AccountTest.class, ClientTest.class }) public class UnitTestSuite {} 

Tratto da qui: http://weblogs.java.net/blog/johnsmart/archive/2010/04/25/grouping-tests-using-junit-categories-0

Inoltre, Arquillian stesso supporta il raggruppamento: https://github.com/weld/core/blob/master/tests-arquillian/src/test/java/org/jboss/weld/tests/Categories.java

Per gestire la distriggerszione globale di questi elementi, JUnit (4.5+) ha due possibilità: utilizzare One come metodo. Se lo metti in @BeforeClass (o @Before) di una class di test, e se la condizione fallisce, ignorerà il test. Nella condizione è ansible inserire una proprietà di sistema o qualcos’altro che può essere triggersto o distriggersto globalmente.

L’altra alternativa è creare un corridore personalizzato che comprenda la proprietà globale e deleghi al corridore appropriato. Questo approccio è molto più fragile (dal momento che i runner interni di JUnit4 sono instabili e possono essere modificati da release a release), ma ha il vantaggio di poter essere ereditato da una gerarchia di classi ed essere sovrascritto in una sottoclass. È anche l’unico modo realistico per farlo se devi supportare le classi JUnit38 legacy.

Ecco un codice per eseguire il Runner personalizzato. Per quanto riguarda ciò che potrebbe fare getAppropriateRunnerForClass, il modo in cui l’ho implementato era di avere un’annotazione separata che dicesse al runner personalizzato su cosa eseguire. L’unica alternativa era una copia di copia molto fragile dal codice JUnit.

 private class CustomRunner implements Runner private Runner runner; public CustomRunner(Class< ?> klass, RunnerBuilder builder) throws Throwable { if (!isRunCustomTests()) { runner = new IgnoredClassRunner(klass); } else { runner = getAppropriateRunnerForClass(klass, builder); } public Description getDescription() { return runner.getDescription(); } public void run(RunNotifier notifier) { runner.run(notifier); } } 

EDIT: il tag @RunWith funziona solo per un’intera class. Un modo per aggirare tale limite è spostare i metodi di prova in una class interna statica e annotarla. In questo modo hai il vantaggio dell’annotazione con l’organizzazione della class. Tuttavia, ciò non aiuterà con i tag @Before o @BeforeClass, dovrai ricreare quelli della class interna. Può chiamare il metodo della class esterna, ma dovrebbe avere il proprio metodo come un hook.

Prova i gruppi di test di JUnit . Dalla documentazione:

 @TestGroup("integration") public class MyIntegrationTest { @ClassRule public static TestGroupRule rule = new TestGroupRule(); ... } 
  • Esegui un semplice gruppo di test: -Dtestgroup = integrazione
  • Esegui più gruppi di test: -Dtestgroup = group1, group2
  • Esegui tutti i gruppi di test: -Dtestgroup = all

È ansible creare oggetti Suite di test contenenti gruppi di test. In alternativa, il tuo IDE (come Eclipse) potrebbe supportare per eseguire tutti i test contenuti in un determinato pacchetto.

Puoi utilizzare Test Suite ( http://qaautomated.blogspot.in/2016/09/junit-test-suits-and-test-execution.html ) oppure puoi Categorie Junit ( http://qaautomated.blogspot.in/ 2016/09 / junit-categories.html ) per raggruppare efficacemente i casi di test.

In JUnit 5 è ansible dichiarare @Tag per i test di filtraggio, a livello di class o di metodo; analogo a testare gruppi in TestNG o Categorie in JUnit 4

Dalla javadoc :

i tag vengono utilizzati per filtrare quali test vengono eseguiti per un determinato piano di test. Ad esempio, un team di sviluppo può taggare i test con valori come “veloce”, “lento”, “ci-server”, ecc. E quindi fornire un elenco di tag da utilizzare per il piano di test corrente, potenzialmente dipendente dall’attuale ambiente.

Ad esempio, è ansible dichiarare una class di test con un @Tag "slow" che verrà ereditato per tutti i metodi e sovrascrivendolo per alcuni metodi, se necessario:

 import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @Tag("slow") public class FooTest{ // @Test void loadManyThings(){ ... } @Test void loadManyManyThings(){ ... } @Test @Tag("fast") void loadFewThings(){ ... } } 

È ansible applicare la stessa logica per altre classi di test.
In questo modo le classi di test (e anche i metodi) appartengono a un tag specifico.

Come buona pratica invece di copiare e incollare @Tag("fast") e @Tag("slow") tutte le classi di test, è ansible creare annotazioni composte personalizzate.
Per esempio :

 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.jupiter.api.Tag; @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Tag("slow") public @interface Fast { } 

e usarlo come:

 @Test @Slow void slowProcessing(){ ... } 

Per abilitare o disabilitare il test contrassegnato con un tag specifico durante l’esecuzione del testo, puoi fare affidamento sulla documentazione di maven-surefire-plugin :

Per includere tag o espressioni tag, utilizzare i groups .

Per escludere tag o espressioni di tag, utilizzare uno o due gruppi excludedGroups .

Basta configurare nel tuo pom.xml il plugin in base alle tue esigenze (esempio del documento):

    ...  org.apache.maven.plugins maven-surefire-plugin 2.22.0  acceptance | !feature-a integration, regression     

Per informazioni la documentazione dell’objective di prova non viene aggiornata.