Crea JUnit Test Suite con esempio: @RunWith @SuiteClasses

⚡ Riepilogo intelligente

JUnit Le suite di test aggregano i casi di test di diverse classi in modo che vengano eseguiti insieme in un'unica passata, grazie alle annotazioni @RunWith(Suite.class) e @SuiteClasses e avviate tramite una normale classe di esecuzione dei test.

  • 🔘 Scopo: Raggruppa i test di più classi in un'unica unità eseguibile anziché avviare ogni classe di test separatamente.
  • ☑️ Annotazioni: L'annotazione @RunWith(Suite.class) delega l'esecuzione, mentre @SuiteClasses elenca tutte le classi che la suite deve eseguire.
  • Passi: Scrivi le classi di test, aggiungi una classe contenitore che trasporta entrambe le annotazioni, quindi eseguila da un JUnitCorridore principale.
  • 🧪 Esempio: Il file JunitTest.java raggruppa SuiteTest1 e SuiteTest2 e la console segnala tre test superati.
  • JUnit 5: Jupiter sostituisce il runner con @Suite più @SelectClasses o @SelectPackages sul motore della suite della piattaforma.
  • ???? insidie: La maggior parte degli errori è causata da suite vuote, importazioni mancanti e una classe suite che contiene i propri metodi @Test.

Creazione di un JUnit suite di test con annotazioni @RunWith e @SuiteClasses

In JUnit, una suite di test ci consente di aggregare tutti casi test da più classi in un unico posto e eseguirle insieme.

Per eseguire la suite di test, è necessario annotare una classe utilizzando le annotazioni indicate di seguito:

  1. @RunWith(Suite.class)
  2. @SuiteClasses(test1.class, test2.class…) oppure @Suite.SuiteClasses({test1.class, test2.class…})

Con le annotazioni di cui sopra, tutte le classi di test nella suite inizieranno a essere eseguite una alla volta. La classe suite stessa rimane vuota: funge solo da contenitore per le annotazioni, e il runner legge tali annotazioni per decidere cosa eseguire.

Passaggi per creare la suite di test e il test runner

I quattro passaggi seguenti costituiscono la suite più piccola effettivamente eseguibile: due classi di test ordinarie, una classe suite che le nomina e un runner che avvia la suite da un metodo main.

Passo 1) Crea una semplice classe di test (ad esempio MyFirstClassTest) e aggiungi un metodo annotato con @Test.

La prima classe contiene un singolo metodo di test vuoto, il che è sufficiente a dimostrare che la suite lo rileva:

La classe MyFirstClassTest in Eclipse dichiarando un @Test annotato myFirstMethod

Passo 2) Crea un'altra classe di test da aggiungere (ad esempio MySecondClassTest) e crea un metodo annotato con @Test.

La seconda classe segue esattamente la stessa struttura, quindi la suite ha due classi separate da aggregare:

La classe MySecondClassTest in Eclipse dichiarazione di un @Test annotato mySecondMethod

Passo 3) Per creare una testSuite è necessario innanzitutto annotare la classe con @RunWith(Suite.class) e @SuiteClasses(class1.class, class2.class…).

Si noti che la classe suite TestSuiteExample non dichiara alcun metodo di test proprio: le due annotazioni contengono tutte le informazioni:

TestSuiteExample annotato con @RunWith(Suite.class) e @SuiteClasses denominati MyFirstClassTest e MySecondClassTest

Passo 4) Crea una classe Test Runner per eseguire la nostra suite di test come mostrato di seguito:

Il corridore è un semplice Java classe con un metodo principale che passa la classe suite a JUnitCore:

chiamata della classe Test runner JUnitCore.runClasses su TestSuiteExample e stampa dell'elenco degli errori

Code Spiegazione:

  • Code Linea 8: Dichiarando il metodo principale della classe Test che eseguirà il nostro JUnit test.
  • Code Linea 9: Esecuzione dei casi di test utilizzando JUnitCore.runClasses accetta come parametro il nome della classe di test (nell'esempio precedente, si utilizza TestSuiteExample.class, come mostrato al passaggio 3).
  • Code Linea 11: Elaborazione del risultato tramite un ciclo for e stampa del risultato non riuscito.
  • Code Linea 13: Stampa del risultato positivo.

Produzione: Ecco l'output che mostra un test riuscito senza errori trace come indicato di seguito:

Eclipse JUnit Visualizza il report Esecuzioni 2/2 con zero errori e zero fallimenti per TestSuiteExample

La barra verde conferma lo scopo di una suite: un'unica esecuzione, un'unica visualizzazione dei risultati ed entrambe le classi vengono riportate sotto il nodo della suite, anziché in due esecuzioni separate.

JUnit Esempio di suite di test

Consideriamo un esempio più complesso, in cui le classi all'interno della suite effettivamente affermare qualcosa invece di contenere un metodo vuoto.

Test Junit.java

JunitTest.java è una semplice classe annotata con @Corri con and @Suite annotazioni. È possibile elencare un numero qualsiasi di classi della suite come parametri, come mostrato di seguito:

package guru99.junit;		
import org.junit.runner.RunWith;		
import org.junit.runners.Suite;		

@RunWith(Suite.class)				
@Suite.SuiteClasses({				
  SuiteTest1.class,
  SuiteTest2.class,  			
})		

public class JunitTest {				
			// This class remains empty, it is used only as a holder for the above annotations		
}

SuiteTest1.java

SuiteTest1.java è una classe di test che ha metodi di test che stampano un messaggio, come mostrato di seguito. Userai questa classe come membro della suite nella classe menzionata sopra. Si basa su una classe helper chiamata JUnitMessaggio, che è definito altrove nello stesso pacchetto e non viene riprodotto qui.

package guru99.junit;		

import static org.junit.Assert.assertEquals;				

import org.junit.Test;		

public class SuiteTest1 {				

    public String message = "Saurabh";							

    JUnitMessage junitMessage = new JUnitMessage(message);							

    @Test(expected = ArithmeticException.class)					
    public void testJUnitMessage() {					

        System.out.println("Junit Message is printing ");					
        junitMessage.printMessage();			

    }		

    @Test		
    public void testJUnitHiMessage() {					
        message = "Hi!" + message;							
        System.out.println("Junit Hi Message is printing ");					
        assertEquals(message, junitMessage.printHiMessage());					
        System.out.println("Suite Test 2 is successful " + message);							
    }		
}		

SuiteTest2.java

SuiteTest2.java è un'altra classe di test, simile a SuiteTest1.java, avendo un metodo di test per stampare un messaggio come indicato di seguito. Userai questa classe come membro della suite in Test Junit.java.

package guru99.junit;		

import org.junit.Assert;		
import org.junit.Test;		

public class SuiteTest2 {				
   	

    @Test		
    public void createAndSetName() {					
        		

        String expected = "Y";					
        String actual = "Y";					

        Assert.assertEquals(expected, actual);					
        System.out.println("Suite Test 1 is successful " + actual);							
    }		

}		

Uscita

Dopo l'esecuzione Test di Junit.java, che contiene una suite contenente SuiteTest1.java and SuiteTest2.java, otterrai l'output seguente. La console stampa i messaggi prodotti da entrambe le classi:

Eclipse Console che mostra i messaggi stampati da entrambe le classi della suite al termine di JunitTest

Migliori JUnit visualizza i record della stessa esecuzione come tre metodi di test superati raggruppati nella classe suite:

Eclipse JUnit Visualizza il report Esegue 3/3 test positivi per JunitTest con SuiteTest1 e SuiteTest2 espansi

Nota: Le etichette della console in questo esempio sono incrociate: la stringa stampata da SuiteTest1 è "Suite Test 2" e quella stampata da SuiteTest2 è "Suite Test 1". Gli elenchi originali sono riprodotti senza modifiche, quindi le etichette rimangono come le ha scritte l'autore; leggere il nome della classe in JUnit Quando si abbina l'output alla sorgente, si fa riferimento all'immagine anziché all'etichetta stampata.

Come creare una suite di test in JUnit 5

JUnit 5 rimuove completamente i runner, quindi @RunWith(Suite.class) non esiste nei pacchetti org.junit.jupiter. Le suite sono state spostate in JUnit Piattaforma, che li spedisce in un artefatto separato chiamato motore della suite della piattaforma JUnitAggiungi quella dipendenza, quindi annota una classe con @Suite e una delle annotazioni del selettore.

import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;
import org.junit.platform.suite.api.SuiteDisplayName;

@Suite
@SuiteDisplayName("Guru99 suite")
@SelectClasses({ SuiteTest1.class, SuiteTest2.class })
public class JunitTest {
    // Empty holder, exactly as in JUnit 4
}

Le annotazioni del selettore sostituiscono l'elenco singolo @SuiteClasses con una piccola famiglia di opzioni:

Annotazione Ciò che seleziona
@SelectClasses Singole classi di test nominate una per una, che sostituiscono direttamente @SuiteClasses.
@SelectPackages Ogni classe di test presente nel pacchetto specificato e in tutti i suoi sottocartelle.
@IncludeClassNamePatterns Un filtro basato su espressioni regolari applicato alla selezione.
@SuiteDisplayName Un nome leggibile visualizzato nel report al posto del nome della classe.

Due ulteriori differenze sono rilevanti nella pratica. A JUnit 5 La classe suite può dichiarare i metodi @BeforeSuite e @AfterSuite, che vengono eseguiti una volta intorno all'intera suite, e JUnit 4 l'esempio sopra è ancora in esecuzione su JUnit La piattaforma utilizza il motore vintage, quindi il codice originale presente in questa pagina non deve essere riscritto per continuare a funzionare.

Vantaggi e limiti di JUnit Suite di prova

Una suite è un gruppoping meccanismo, non un framework di test di per sé, e questo determina sia ciò che fa bene sia dove smette di essere utile.

Vantaggi

  • Un lancio esegue insieme classi correlate, quindi un set di fumo o un regressione L'operazione di set viene avviata con un singolo comando.
  • La visualizzazione dei risultati raggruppa tutte le classi sotto un unico nodo di suite, il che rende più facile individuare un errore comune.
  • L'elenco dei membri risiede nel codice sorgente, quindi viene revisionato e gestito in termini di versioni come qualsiasi altro file sorgente.
  • La stessa classe suite può essere avviata da un IDE, da un runner come JUnitCore, oppure da uno strumento di compilazione.

limitazioni

  • @SuiteClasses è un elenco predefinito, quindi una nuova classe di test viene silenziosamente omessa finché qualcuno non modifica la suite.
  • La suite non offre alcuna garanzia di ordinamento al di là dell'ordine in cui le lezioni sono elencate.
  • Nulla è condiviso tra le diverse classi di appartenenza, quindi una suite non sostituisce un immobile fisso o una classe base.
  • Gli strumenti di compilazione individuano già le classi di test tramite convenzioni di denominazione, il che rende una suite ridondante in molti progetti.

Errori comuni durante la creazione di un JUnit Suite di prova

La maggior parte dei problemi relativi alle suite di software produce un messaggio breve e poco utile. La tabella illustra i messaggi che è più probabile ricevere, la loro causa e la soluzione.

Messaggio o sintomo Causare Fissare
Errore di inizializzazione: nessun metodo eseguibile La classe viene eseguita come una normale classe di test, ma contiene solo annotazioni. Aggiungi @RunWith(Suite.class) in modo che il runner della suite prenda il sopravvento al posto del runner predefinito.
Impossibile trovare il simbolo: classe Suite L'importazione della suite non è presente. Importa org.junit.runners.Suite insieme a org.junit.runner.RunWith.
La suite è in esecuzione, ma una lezione viene saltata. La classe non è mai stata aggiunta all'elenco @SuiteClasses. Aggiungi esplicitamente la classe oppure spostala in @SelectPackages in JUnit 5.
Il nome della classe non è accettato dal compilatore. @Runwith o @suiteClasses è stato digitato con la maiuscola/minuscola errata. Java Le annotazioni fanno distinzione tra maiuscole e minuscole: scrivi @RunWith e @SuiteClasses esattamente come sono scritte.
I test nella classe suite stessa non vengono mai eseguiti È stato aggiunto un metodo @Test al contenitore della suite. Mantieni vuoto il contenitore e sposta il metodo di test in una classe membro.

Scrivere la suite una volta e mantenerlaping è accurato è il vero lavoro. Se l'elenco si discosta dalle classi sul disco, la suite segnala verde mentre parte del test unitario set non viene mai eseguito affatto, una delle modalità di errore più silenziose in test del software.

DOMANDE FREQUENTI

La suite esegue le classi nell'ordine in cui sono elencate, ma JUnit Non offre alcuna garanzia sull'ordine dei metodi all'interno di ciascuna classe. I test che dipendono dall'esecuzione di un test precedente sono fragili e dovrebbero essere riscritti in modo da essere indipendenti.

Sì. Una classe suite è una classe ordinaria per quanto riguarda il runner, quindi nominarla all'interno di un altro elenco @SuiteClasses annida le suite. L'annidamento è utile per una suite di regressione di livello superiore costruita a partire da suite di moduli più piccoli.

Gli assistenti IA leggono le classi di test sul disco, le confrontano con l'elenco @SuiteClasses e segnalano le classi che non sono mai state aggiunte. Inoltre, raggruppano gli errori ripetuti. traces per causa principale, che abbrevia il triage dopo che una suite segnala molti rossi contemporaneamente.

Secondo pilota scrive la coppia di annotazioni rapidamente, ma spesso mescola JUnit 4 e JUnit 5 importazioni nello stesso file. Verifica che org.junit.runners.Suite e org.junit.platform.suite.api.Suite non compaiano mai insieme, perché solo uno di essi corrisponde al tuo runner.

Aggiungi junit-platform-suite-engine all'ambito del test. Le annotazioni @Suite e @SelectClasses si trovano in junit-platform-suite-api, che questo artefatto del motore include in modo transitivo, quindi di solito è sufficiente una singola dipendenza.

Di solito no. Surefire e il Gradle Il compito di test individua già le classi di test tramite un modello di denominazione e le esegue tutte. Vale la pena scrivere una suite quando si desidera un sottoinsieme denominato, come un set di fumo, che sia più piccolo dell'esecuzione completa.

Il runner segnala un errore di inizializzazione per quel membro, indicando che non sono stati trovati metodi eseguibili e che l'intera suite è stata contrassegnata come fallita. Rimuovere la voce o aggiungere un metodo @Test alla classe.

Non all'interno di un elenco di selezione. Mantieni il JUnit 4 classi sul motore vintage e selezionale da un JUnit 5 suite per pacchetto, quindi entrambi i motori funzionano sotto lo stesso JUnit Avvio della piattaforma senza mescolare famiglie di annotazioni.

Riassumi questo post con: