creëren JUnit Testsuite met voorbeeld: @RunWith @SuiteClasses

⚡ Slimme samenvatting

JUnit Testsuites bundelen testgevallen uit verschillende klassen, zodat ze samen in één doorgang worden uitgevoerd. Dit wordt aangestuurd door de annotaties @RunWith(Suite.class) en @SuiteClasses en gestart via een gewone testrunnerklasse.

  • 🔘 Doel: Groepeer tests van meerdere klassen in één uitvoerbare eenheid in plaats van elke testklasse afzonderlijk te starten.
  • ☑️ aantekeningen: @RunWith(Suite.class) delegeert de uitvoering, terwijl @SuiteClasses elke klasse opsomt die de suite moet uitvoeren.
  • Stappen: Schrijf de testklassen, voeg een containerklasse toe die beide annotaties bevat, en voer deze vervolgens uit vanuit een JUnitKernsporter.
  • 🧪 Voorbeeld: JunitTest.java groepeert SuiteTest1 en SuiteTest2, en de console meldt dat drie tests geslaagd zijn.
  • JUnit 5: Jupiter vervangt de runner door @Suite plus @SelectClasses of @SelectPackages op de platform suite engine.
  • 📌 Valkuilen: Lege testsuites, ontbrekende imports en een suiteklasse die zijn eigen @Test-methoden bevat, veroorzaken de meeste fouten.

Een maken JUnit testsuite met @RunWith- en @SuiteClasses-annotaties

In JUnitEen testsuite stelt ons in staat om alles samen te voegen. testgevallen meerdere klassen op één plek samenbrengen en ze tegelijkertijd uitvoeren.

Om de testsuite uit te voeren, moet u een klasse annoteren met behulp van de onderstaande annotaties:

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

Met de bovenstaande annotaties zullen alle testklassen in de suite één voor één worden uitgevoerd. De suiteklasse zelf blijft leeg: het is slechts een container voor de annotaties, en de runner leest die annotaties om te bepalen wat er moet worden uitgevoerd.

Stappen om Test Suite en Test Runner te maken

De vier onderstaande stappen bouwen de kleinste testsuite die daadwerkelijk werkt: twee gewone testklassen, een suiteklasse die ze benoemt, en een runner die de suite start vanuit een main-methode.

Stap 1) Maak een eenvoudige testklasse (bijvoorbeeld MyFirstClassTest) en voeg een methode toe die is geannoteerd met @Toets.

De eerste klasse bevat één lege testmethode, wat voldoende is om aan te tonen dat de testsuite deze herkent:

Mijn eerste klassetest in Eclipse een @Test-geannoteerde myFirstMethod declareren

Stap 2) Maak een extra testklasse aan (bijvoorbeeld MySecondClassTest) en maak een methode aan die is geannoteerd met @Test.

De tweede klasse heeft exact dezelfde vorm, dus de suite bestaat uit twee afzonderlijke klassen die samengevoegd moeten worden:

MijnSecondClassTest-klasse in Eclipse een @Test-geannoteerde mySecondMethod declareren

Stap 3) Om een ​​testsuite te maken, moet je de klasse eerst annoteren met @RunWith(Suite.class) en @SuiteClasses(class1.class, class2.class…).

Merk op dat de suiteklasse TestSuiteExample geen eigen testmethode declareert — de twee annotaties bevatten alle informatie:

TestSuiteExample geannoteerd met @RunWith(Suite.class) en @SuiteClasses met de namen MyFirstClassTest en MySecondClassTest

Stap 4) Maak een Test Runner-klasse aan om onze testsuite uit te voeren zoals hieronder beschreven:

De hardloper is een vlakte Java klasse met een hoofdmethode die de suiteklasse doorgeeft aan JUnitKern:

Testrunner-klasse oproep JUnitCore.runClasses op TestSuiteExample en het afdrukken van de lijst met fouten

Code Uitleg:

  • Code Regel 8: De hoofdmethode van de klasse Test declareren, die onze test zal uitvoeren. JUnit test.
  • Code Regel 9: Testcases uitvoeren met behulp van JUnitCore.runClasses neemt de naam van de testklasse als parameter (in het bovenstaande voorbeeld gebruikt u TestSuiteExample.class, zoals weergegeven in stap 3).
  • Code Regel 11: Het resultaat verwerken met een for-loop en het mislukte resultaat afdrukken.
  • Code Regel 13: Het succesvolle resultaat afdrukken.

Output: Hieronder staat de uitvoer, waaruit blijkt dat de test succesvol is verlopen zonder fouten. trace zoals hieronder weergegeven:

Eclipse JUnit Bekijk de rapportage. TestSuiteExample heeft 2 van de 2 tests succesvol afgerond zonder fouten of mislukkingen.

De groene balk bevestigt waar een suite voor dient: één lancering, één resultaatweergave en beide klassen worden onder het suiteknooppunt gerapporteerd in plaats van in twee afzonderlijke uitvoeringen.

JUnit Voorbeeld van een testsuite

Laten we een complexer voorbeeld bekijken, waarin de klassen binnen de suite daadwerkelijk beweren iets in plaats van een lege methode te bewaren.

JunitTest.java

JunitTest.java is een eenvoudige klasse die is geannoteerd met de @Rennen met en @Suite annotaties. U kunt een willekeurig aantal klassen in de suite als parameters opgeven, zoals hieronder weergegeven:

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 Dit is een testklasse met testmethoden die een bericht afdrukken, zoals hieronder weergegeven. Je gebruikt deze klasse als suitelid in de hierboven genoemde klasse. De klasse is afhankelijk van een hulpklasse genaamd JUnitBericht, dat elders in hetzelfde pakket is gedefinieerd en hier niet wordt weergegeven.

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 is een andere testklasse, vergelijkbaar met SuiteTest1.java, met een testmethode om een ​​bericht af te drukken zoals hieronder weergegeven. Je gebruikt deze klasse als een suite-lid in 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);							
    }		

}		

uitgang

Na het uitvoeren van JunitTest.java, dat een suite bevat met daarin SuiteTest1.java en SuiteTest2.javaJe krijgt dan de onderstaande uitvoer te zien. De console print de berichten die door beide klassen worden geproduceerd:

Eclipse Console met de afgedrukte berichten van beide suiteklassen nadat JUnitTest is voltooid

De JUnit De weergave registreert dezelfde uitvoering als drie geslaagde testmethoden die zijn gegroepeerd onder de suiteklasse:

Eclipse JUnit Rapportage toont 3/3 groene resultaten voor JUnitTest met SuiteTest1 en SuiteTest2 uitgevouwen.

Let op: In dit voorbeeld zijn de consolelabels doorgestreept: de string die door SuiteTest1 wordt afgedrukt, luidt "Suite Test 2" en de string die door SuiteTest2 wordt afgedrukt, luidt "Suite Test 1". De originele lijsten zijn ongewijzigd overgenomen, dus de labels blijven zoals de auteur ze heeft geschreven; lees de klassenaam in de JUnit Gebruik de weergave in plaats van het afgedrukte label wanneer u de uitvoer aan de bron koppelt.

Hoe maak je een testsuite aan in JUnit 5

JUnit Versie 5 verwijdert runners volledig, waardoor @RunWith(Suite.class) niet meer bestaat in de org.junit.jupiter-pakketten. Suites zijn verplaatst naar de JUnit Platform, dat ze verzendt in een apart artefact genaamd junit-platform-suite-engineVoeg die afhankelijkheid toe en annoteer vervolgens een klasse met @Suite en een van de selector-annotaties.

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
}

De selector-annotaties vervangen de enkele @SuiteClasses-lijst door een kleine reeks opties:

aantekening Wat het selecteert
@SelectClasses Individuele testklassen worden één voor één benoemd, de directe vervanging voor @SuiteClasses.
@SelectPackages Elke testklasse in het genoemde pakket en in al zijn subpakketten.
@IncludeClassNamePatterns Een filter op basis van reguliere expressies wordt toegepast op de selectie.
@SuiteDisplayName In het rapport wordt een leesbare naam weergegeven in plaats van de klassenaam.

Twee andere verschillen zijn in de praktijk van belang. A JUnit Een suiteklasse kan de methoden @BeforeSuite en @AfterSuite declareren, die eenmaal voor de hele suite worden uitgevoerd. JUnit Het bovenstaande voorbeeld (4) wordt nog steeds uitgevoerd op de JUnit Het platform maakt gebruik van de vintage engine, waardoor de originele code op deze pagina niet hoeft te worden herschreven om te blijven functioneren.

Voordelen en beperkingen van JUnit Testsuites

Een suite is een groepping mechanisme, geen testkader Het heeft een eigen karakter, en dat bepaalt zowel wat het goed doet als waar het ophoudt nuttig te zijn.

Voordelen

  • Eén lancering voert gerelateerde klassen samen uit, dus een rookset of een regressie De set wordt gestart met één enkel commando.
  • De resultaatweergave groepeert alle klassen onder één suiteknooppunt, waardoor een gedeelde fout gemakkelijker te herkennen is.
  • De ledenlijst staat in de code, dus deze wordt net als elk ander bronbestand gecontroleerd en van versiebeheer voorzien.
  • Dezelfde suiteklasse kan worden gestart vanuit een IDE, vanuit een runner zoals JUnitCore, of vanuit een buildtool.

Beperkingen

  • @SuiteClasses is een vastgelegde lijst, waardoor een nieuwe testklasse stilzwijgend wordt weggelaten totdat iemand de suite bewerkt.
  • De suite biedt geen andere volgorde dan de volgorde waarin de lessen worden vermeld.
  • Er is geen sprake van gedeelde functionaliteit tussen de verschillende lidklassen, dus een suite is geen vervanging voor een fixture of een basisklasse.
  • Buildtools detecteren testklassen al op basis van naamgevingsconventies, waardoor een complete testsuite in veel projecten overbodig is.

Veelvoorkomende fouten bij het maken van een JUnit Test pak

De meeste problemen met softwarepakketten leveren een kort, weinig behulpzaam bericht op. De tabel koppelt de meest voorkomende berichten aan hun oorzaak en oplossing.

Bericht of symptoom Veroorzaken Bepalen
initialisatiefout: Geen uitvoerbare methoden gevonden De klasse wordt uitgevoerd als een gewone testklasse, maar bevat alleen annotaties. Voeg @RunWith(Suite.class) toe zodat de suite-runner het overneemt in plaats van de standaardrunner.
symbool niet gevonden: klasse Suite De Suite-import ontbreekt. Importeer org.junit.runners.Suite samen met org.junit.runner.RunWith.
De suite draait wel, maar een les wordt overgeslagen. De klasse is nooit toegevoegd aan de @SuiteClasses-lijst. Voeg de klasse expliciet toe, of verplaats deze naar @SelectPackages in JUnit 5.
De klassenaam wordt niet geaccepteerd door de compiler. @Runwith of @suiteClasses is met een verkeerde hoofdlettergevoeligheid getypt. Java Annotaties zijn hoofdlettergevoelig: schrijf @RunWith en @SuiteClasses exact zo.
Tests in de suiteklasse zelf worden nooit uitgevoerd. Er is een @Test-methode toegevoegd aan de suitehouder. Laat de houder leeg en verplaats de testmethode naar een lidklasse.

Schrijf de suite één keer en bewaar hem.ping De nauwkeurigheid is waar het echt om draait. Als de lijst afwijkt van de klassen op de schijf, geeft de suite een groen signaal, terwijl een deel van de lijst dat niet doet. hoofdstuk toets De set-opdracht wordt helemaal niet uitgevoerd, een van de meest onopvallende foutmodi. software testen.

Veelgestelde vragen

De suite voert de klassen uit in de volgorde waarin ze zijn opgesomd, maar JUnit Geeft geen garantie over de volgorde van methoden binnen elke klasse. Tests die afhankelijk zijn van een eerdere test zijn kwetsbaar en moeten worden herschreven zodat ze op zichzelf staan.

Ja. Een suiteklasse is een gewone klasse vanuit het perspectief van de runner, dus door deze binnen een andere `@SuiteClasses`-lijst te benoemen, worden de suites genest. Nesting is handig voor een regressietestsuite op het hoogste niveau, opgebouwd uit kleinere modulesuites.

AI-assistenten lezen de testklassen op schijf, vergelijken ze met de @SuiteClasses-lijst en markeren klassen die nooit zijn toegevoegd. Ze clusteren ook herhaalde fouten. traces op basis van de hoofdoorzaak, wat de triage verkort nadat een testsuite veel rode meldingen tegelijk heeft gerapporteerd.

Copilot schrijft het annotatiepaar snel, maar het verwisselt het vaak. JUnit 4 en JUnit 5 imports in hetzelfde bestand. Controleer of org.junit.runners.Suite en org.junit.platform.suite.api.Suite nooit samen voorkomen, omdat slechts één ervan overeenkomt met uw runner.

Voeg junit-platform-suite-engine toe aan de testscope. De annotaties @Suite en @SelectClasses bevinden zich in junit-platform-suite-api, dat door dit engine-artefact indirect wordt geïmporteerd, dus één afhankelijkheid is normaal gesproken voldoende.

Meestal niet. Surefire en de Gradle De testtaak detecteert testklassen al aan de hand van naamgevingspatronen en voert ze allemaal uit. Het schrijven van een testsuite is nuttig wanneer je een benoemde subset wilt, zoals een 'smoke set', die kleiner is dan de volledige testrun.

De runner meldt een initialisatiefout voor dat lid, met de melding dat er geen uitvoerbare methoden zijn gevonden, en de hele testsuite wordt als mislukt gemarkeerd. Verwijder de vermelding of voeg een @Test-methode toe aan de klasse.

Niet binnen één selectielijst. Behoud de JUnit 4 klassen op de oldtimer-motor en selecteer ze uit een JUnit 5 suites per pakket, zodat beide engines onder dezelfde omstandigheden draaien. JUnit Platformlancering zonder het combineren van annotatiefamilies.

Vat dit bericht samen met: