Skapa JUnit Testa Suite med exempel: @RunWith @SuiteClasses

⚡ Smart sammanfattning

JUnit Testsviter aggregerar testfall från flera klasser så att de körs tillsammans i ett enda steg, drivna av annoteringarna @RunWith(Suite.class) och @SuiteClasses och startade via en vanlig testkörningsklass.

  • 🔘 Syfte: Gruppera tester från många klasser till en körbar enhet istället för att starta varje testklass separat.
  • ☑️ anteckningar: @RunWith(Suite.class) delegerar körning, medan @SuiteClasses listar varje klass som sviten måste köra.
  • Steg: Skriv testklasserna, lägg till en innehavarklass som bär båda annoteringarna och kör den sedan från en JUnitKärnlöpare.
  • 🧪 Exempel: JunitTest.java grupperar SuiteTest1 och SuiteTest2, och konsolen rapporterar tre godkända tester.
  • 🛠️ JUnit 5: Jupiter ersätter löparen med @Suite plus @SelectClasses eller @SelectPackages i plattformssvitens motor.
  • 📌 Fallgropar: Tomma sviter, saknade importer och en svitklass som innehåller sina egna @Test-metoder orsakar de flesta fel.

Skapa ett JUnit testsvit med @RunWith- och @SuiteClasses-annoteringar

In JUnit, en testsvit låter oss aggregera alla testfall från flera klasser på ett ställe och köra dem tillsammans.

För att köra suite-testet måste du annotera en klass med hjälp av nedanstående annoteringar:

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

Med ovanstående annoteringar kommer alla testklasser i sviten att börja köras en efter en. Själva sviten förblir tom: den är bara en hållare för annoteringarna, och löparen läser dessa annoteringar för att bestämma vad som ska köras.

Steg för att skapa Test Suite och Test Runner

De fyra stegen nedan bygger den minsta sviten som faktiskt körs: två vanliga testklasser, en sviteklass som namnger dem och en runner som startar sviten från en main-metod.

Steg 1) Skapa en enkel testklass (t.ex. MyFirstClassTest) och lägg till en metod kommenterad med @Testa.

Den första klassen innehåller en enda tom testmetod, vilket är tillräckligt för att bevisa att sviten plockar upp den:

MyFirstClassTest-kurs i Eclipse deklarera en @Test-annoterad myFirstMethod

Steg 2) Skapa en annan testklass att lägga till (t.ex. MySecondClassTest) och skapa en metod kommenterad med @Test.

Den andra klassen följer exakt samma form, så sviten har två separata klasser att aggregera:

MySecondClassTest-kurs i Eclipse deklarerar en @Test-annoterad mySecondMethod

Steg 3) För att skapa en testSuite måste du först annotera klassen med @RunWith(Suite.class) och @SuiteClasses(class1.class, class2.class…).

Observera att suite-klassen TestSuiteExample inte deklarerar någon egen testmetod — de två annoteringarna innehåller all information:

TestSuiteExample kommenterat med @RunWith(Suite.class) och @SuiteClasses som namnger MyFirstClassTest och MySecondClassTest

Steg 4) Skapa en Test Runner-klass för att köra vår testsvit enligt nedan:

Löparen är en slät Java klass med en main-metod som överlämnar suite-klassen till JUnitKärna:

Anrop till testlöparklass JUnitCore.runClasses på TestSuiteExample och utskrift av fellistan

Code Förklaring:

  • Code Linje 8: Deklarera huvudmetoden för klassen Test som kommer att köra vår JUnit testet.
  • Code Linje 9: Exekvera testfall med hjälp av JUnitCore.runClasses som tar testklassnamnet som en parameter (i exemplet ovan använder du TestSuiteExample.class som visas i steg 3).
  • Code Linje 11: Bearbetar resultatet med en for-loop och skriver ut det misslyckade resultatet.
  • Code Linje 13: Skriver ut det lyckade resultatet.

Produktion: Här är resultatet som visar ett lyckat test utan fel trace enligt nedan:

Eclipse JUnit visa rapportering Körningar 2/2 med noll fel och noll misslyckanden för TestSuiteExample

Den gröna stapeln bekräftar vad en svit är till för: en start, en resultatvy och båda klasserna rapporteras under svitnoden snarare än i två separata körningar.

JUnit Exempel på testsvit

Tänk dig ett mer komplext exempel, där klasserna inuti sviten faktiskt hävda något istället för att hålla en tom metod.

JunitTest.java

JunitTest.java är en enkel klass kommenterad med @Spring med och @Svit anteckningar. Du kan lista valfritt antal klasser i sviten som parametrar, enligt nedan:

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 är en testklass som har testmetoder som skriver ut ett meddelande, enligt nedan. Du kommer att använda den här klassen som en svitmedlem i klassen som nämns ovan. Den förlitar sig på en hjälpklass med namnet JUnitMeddelande, som definieras på annan plats i samma paket och inte återges här.

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 är en annan testklass, liknande SuiteTest1.java, med en testmetod för att skriva ut ett meddelande enligt nedan. Du kommer att använda den här klassen som en svitmedlem i JunitTest.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);							
    }		

}		

Produktion

Efter att ha utförts JunitTest.java, som innehåller en svit som innehåller SuiteTest1.java och SuiteTest2.java, får du utdata nedan. Konsolen skriver ut meddelandena som produceras av båda klasserna:

Eclipse Konsol som visar de utskrivna meddelandena från båda svitklasserna efter att JunitTest är klar

Ocuco-landskapet JUnit visa poster samma körning som tre godkända testmetoder grupperade under suite-klassen:

Eclipse JUnit visa rapportering Körs 3/3 grönt för JunitTest med SuiteTest1 och SuiteTest2 utökade

Obs: Konsoletiketterna i det här exemplet är överstrukna — strängen som skrivs ut av SuiteTest1 lyder "Suite Test 2" och den som skrivs ut av SuiteTest2 lyder "Suite Test 1". De ursprungliga listningarna reproduceras oförändrade, så etiketterna förblir som författaren skrev dem; läs klassnamnet i JUnit vyn snarare än den utskrivna etiketten när du matchar utdata med källan.

Hur man skapar en testsvit i JUnit 5

JUnit 5 tar bort runners helt och hållet, så @RunWith(Suite.class) finns inte i org.junit.jupiter-paketen. Suites flyttades till JUnit Plattform, som skickar dem i en separat artefakt som kallas junit-plattforms-svit-motorLägg till det beroendet och annotera sedan en klass med @Suite och en av selektorannoteringarna.

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
}

Selektorannoteringarna ersätter den enda @SuiteClasses-listan med en liten familj av alternativ:

anteckning Vad den väljer
@SelectClasses Enskilda testklasser namnges en efter en, den direkta ersättningen för @SuiteClasses.
@SelectPakets Varje testklass i det namngivna paketet och i alla dess underpaket.
@IncludeClassNamePatterns Ett filter för reguljära uttryck appliceras ovanpå markeringen.
@SuiteDisplayName Ett läsbart namn som visas i rapporten istället för klassnamnet.

Ytterligare två skillnader spelar roll i praktiken. JUnit 5-svitklassen kan deklarera @BeforeSuite- och @AfterSuite-metoderna, som körs en gång runt hela sviten, och JUnit 4 exempel ovan körs fortfarande på JUnit Plattformen genom den gamla motorn, så att originalkoden på den här sidan inte behöver skrivas om för att fortsätta fungera.

Fördelar och begränsningar med JUnit Testsviter

En svit är en gruppping mekanism, inte en testramverk av sig själv, och det formar både vad den gör bra och var den slutar vara användbar.

Fördelar

  • En uppskjutning kör relaterade klasser tillsammans, så en rökuppsättning eller en regression set startas med ett enda kommando.
  • Resultatvyn grupperar varje klass under en svitnod, vilket gör det lättare att upptäcka ett delat fel.
  • Medlemslistan finns i kod, så den granskas och versioneras som vilken annan källfil som helst.
  • Samma svitklass kan startas från en IDE, från en runner som t.ex. JUnitKärna, eller från ett byggverktyg.

Begränsningar

  • @SuiteClasses är en hårdkodad lista, så en ny testklass utelämnas tyst tills någon redigerar sviten.
  • Sviten ger ingen ordningsgaranti utöver den ordning i vilken klasserna listas.
  • Ingenting delas mellan medlemsklasserna, så en svit är inte en ersättning för en fixtur eller en basklass.
  • Byggverktyg identifierar redan testklasser genom namngivningskonventioner, vilket gör en svit överflödig i många projekt.

Vanliga fel när man skapar en JUnit Test svit

De flesta problem i sviterna ger ett kort, ohjälpsamt meddelande. Tabellen kopplar de meddelanden du sannolikt kommer att stöta på till deras orsak och åtgärda dem.

Meddelande eller symptom Orsak Fast
initialiseringsfel: Inga körbara metoder Klassen körs som en vanlig testklass, men den innehåller endast annoteringar. Lägg till @RunWith(Suite.class) så att suite-löparen tar över istället för standardlöparen.
kan inte hitta symbolen: klass Suite Suite-importen saknas. Importera org.junit.runners.Suite tillsammans med org.junit.runner.RunWith.
Sviten körs, men en kurs hoppas över Klassen lades aldrig till i @SuiteClasses-listan. Lägg till klassen explicit, eller flytta den till @SelectPackages i JUnit 5.
Klassnamnet accepteras inte av kompilatorn @Runwith eller @suiteClasses skrevs med fel skiftläge. Java Annoteringar är skiftlägeskänsliga: skriv @RunWith och @SuiteClasses exakt.
Tester i själva suite-klassen körs aldrig En @Test-metod lades till i suite-hållaren. Låt hållaren vara tom och flytta testmetoden till en medlemsklass.

Att skriva sviten en gång och hållaping Det är korrekt om det är det verkliga arbetet. Om listan avviker från klasserna på disken, rapporteras sviten grönt medan en del av enhetstest set körs aldrig alls, ett av de tystaste fellägena i mjukvarutestning.

Vanliga frågor

Sviten kör klasserna i den ordning de listas, men JUnit ger ingen garanti för ordningen på metoderna inom varje klass. Tester som är beroende av att ett tidigare test har körts är känsliga och bör skrivas om för att stå fristående.

Ja. En svitklass är en vanlig klass vad gäller löparen, så att namnge den i en annan @SuiteClasses-lista kapslar sviterna. Kapsling är användbart för en regressionssvit på toppnivå som är byggd av mindre modulsviter.

AI-assistenter läser testklasserna på disken, jämför dem med @SuiteClasses-listan och flaggar klasser som aldrig lades till. De klustrar också upprepade fel. traces efter grundorsak, vilket förkortar triage efter att en svit rapporterar många röda ögon samtidigt.

Copilot skriver annoteringsparet snabbt, men det blandas ofta JUnit 4 och JUnit 5 importer i samma fil. Kontrollera att org.junit.runners.Suite och org.junit.platform.suite.api.Suite aldrig visas tillsammans, eftersom bara en av dem matchar din runner.

Lägg till junit-platform-suite-engine i testomfånget. Annoteringarna @Suite och @SelectClasses finns i junit-platform-suite-api, som den motorartefakten hämtar transitivt, så ett enda beroende räcker normalt.

Vanligtvis inte. Surefire och Gradle Testuppgiften upptäcker redan testklasser genom att namnge mönster och kör dem alla. En svit är värd att skriva när du vill ha en namngiven delmängd, till exempel en rökmängd, som är mindre än hela körningen.

Löparen rapporterar ett initialiseringsfel för den medlemmen och anger att inga körbara metoder hittades, och hela sviten markeras som misslyckad. Ta bort posten eller lägg till en @Test-metod i klassen.

Inte inom en väljarlista. Behåll JUnit 4 klasser på veteranmotorn och välj dem från en JUnit 5 sviter per paket, så båda motorerna körs under samma JUnit Plattformslansering utan att blanda annoteringsfamiljer.

Sammanfatta detta inlägg med: