Domanda

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

O è possibile annotare alcuni test e poi disabilitarli globalmente?

Sto usando JUnit 4 , non posso usare TestNG.

modifica: @RunWith e @SuiteClasses funzionano alla grande. Ma è possibile annotare in questo modo solo alcuni test nella classe di test? O devo annotare l'intera classe di test?

È stato utile?

Soluzione

Vuoi raggruppare i test all'interno di una classe di test o vuoi raggruppare le classi di test? Presumo quest'ultimo.

Dipende da come stai eseguendo i test. Se li esegui da Maven, è possibile specificare esattamente quali test si desidera includere. Vedere la documentazione Maven surefire per questo.

Più in generale, tuttavia, quello che faccio è che ho un albero di suite di test. Una suite di test in JUnit 4 è simile a:

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

Quindi, forse ho una FunctionTestsSuite e una UnitTestsSuite, e quindi una AllTestsSuite che include le altre due. Se li esegui in Eclipse otterrai una vista gerarchica molto bella.

Il problema con questo approccio è che è un po 'noioso se si desidera suddividere i test in più di un modo diverso. Ma è ancora possibile (ad esempio puoi avere una serie di suite che si dividono in base al modulo, quindi un'altra sezione sul tipo di test).

Altri suggerimenti

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 le disabilitazioni a livello globale, JUnit (4.5+) ha due modi per usare il nuovo metodo assumeThat. Se lo metti nella @BeforeClass (o nella @Before) di una classe di test, e se la condizione fallisce, ignorerà il test. Nella condizione puoi mettere una proprietà di sistema o qualcos'altro che può essere attivato o disattivato a livello globale.

L'altra alternativa è quella di creare un corridore personalizzato che comprenda la proprietà globale e deleghi al corridore appropriato. Questo approccio è molto più fragile (poiché i corridori interni di JUnit4 sono instabili e possono essere cambiati da una versione all'altra), ma ha il vantaggio di poter essere ereditato in una gerarchia di classi ed essere sovrascritto in una sottoclasse. È anche l'unico modo realistico per farlo se devi supportare le classi JUnit38 legacy.

Ecco un po 'di codice per eseguire il Runner personalizzato. Per quanto riguarda ciò che getAppropriateRunnerForClass potrebbe fare, il modo in cui l'ho implementato era di avere un'annotazione separata che dicesse al runner personalizzato con cosa eseguire. L'unica alternativa era una copia molto fragile del 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 classe. Un modo per aggirare quella limitazione è spostare i metodi di prova in una classe interna statica e annotarla. In questo modo hai il vantaggio dell'annotazione con l'organizzazione della classe. Ma farlo non aiuta con i tag @Before o @BeforeClass, dovrai ricreare quelli nella classe interna. Può chiamare il metodo della classe esterna, ma dovrebbe avere il suo metodo come hook.

Prova Gruppi di test JUnit . Dalla documentazione:

@TestGroup("integration")
public class MyIntegrationTest {
   @ClassRule
   public static TestGroupRule rule = new TestGroupRule();

   ...
}
  • Esegue un semplice gruppo di test: -Dtestgroup = integrazione
  • Esegue più gruppi di test: -Dtestgroup = group1, group2
  • Esegue tutti i gruppi di test: -Dtestgroup = all

In JUnit 5 puoi dichiarare @Tag per i test di filtro, sia a livello di classe che di metodo; analogo ai gruppi di test in TestNG o Categorie in JUnit 4

Dal javadoc :

  I tag

vengono utilizzati per filtrare i test eseguiti per un determinato test   Piano. Ad esempio, un team di sviluppo può etichettare i test con valori del genere   come "veloce", "lento", "ci-server", ecc. e quindi fornire un elenco di tag a   essere utilizzato per l'attuale piano di test, potenzialmente dipendente dal   ambiente corrente.

Ad esempio, potresti dichiarare una classe di test con un " slow " @Tag che verrà ereditato per tutti i metodi e sovrascriverlo 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(){ 
        ...
   }

}

È possibile 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 ") in tutte le classi di test, puoi creare annotazioni composte personalizzate.
Ad 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 Slow {
}

e usalo come:

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

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

  

Per includere tag o espressioni di tag, utilizzare group .

     

Per escludere tag o espressioni di tag, utilizzare excludedGroups .

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

 <build>
     <plugins>
         ...
         <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-surefire-plugin</artifactId>
             <version>2.22.0</version>
             <configuration>
                 <groups>acceptance | !feature-a</groups>
                 <excludedGroups>integration, regression</excludedGroups>
             </configuration>
         </plugin>
     </plugins> 
</build> 

Per informazioni la documentazione obiettivo test è non aggiornato.

Puoi creare oggetti Suite di test. In alternativa, il tuo IDE (come Eclipse) potrebbe avere il supporto per l'esecuzione di 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 Junit Categories ( http://qaautomated.blogspot.in/2016/09/junit-categories.html ) per raggruppare i casi di test in modo efficace.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top