Teremt JUnit Tesztcsomag példával: @RunWith @SuiteClasses

⚡ Okos összefoglaló

JUnit A tesztcsomagok több osztályból származó teszteseteket összesítenek, így egyetlen menetben futnak együtt, a @RunWith(Suite.class) és @SuiteClasses annotációk vezérlik őket, és egy hagyományos tesztfuttató osztályon keresztül indítják el őket.

  • 🔘 Cél: Csoportosítsd több osztály tesztjeit egyetlen futtatható egységbe ahelyett, hogy minden tesztosztályt külön futtatnál.
  • ☑️ Magyarázatok: A @RunWith(Suite.class) delegálja a végrehajtást, míg a @SuiteClasses felsorolja az összes osztályt, amelyet a csomagnak futtatnia kell.
  • Lépések: Írd meg a tesztosztályokat, adj hozzá egy olyan tartóosztályt, amely mindkét annotációt tartalmazza, majd futtasd le egy JUnitMagfutó.
  • 🧪 Példa: A JunitTest.java csoportosítja a SuiteTest1 és SuiteTest2 teszteket, és a konzol három sikeres tesztet jelez.
  • 🇧🇷 JUnit 5: A Jupiter a futót a platformcsomag motorján @Suite-re, valamint @SelectClasses-re vagy @SelectPackages-re cseréli.
  • 📌 Buktatók: Az üres csomagok, a hiányzó importálások és a saját @Test metódusokkal rendelkező csomagosztályok okozzák a legtöbb hibát.

Sikeres  JUnit tesztcsomag @RunWith és @SuiteClasses annotációkkal

In JUnitegy tesztkészlet lehetővé teszi számunkra, hogy összesítsük az összes teszt esetek több osztályból egy helyen, és együtt futtathatók.

A csomagteszt futtatásához az alábbi annotációkkal kell annotálnia egy osztályt:

  1. @RunWith(Suite.class)
  2. @SuiteClasses(teszt1.osztály, teszt2.osztály…) vagy @Suite.SuiteClasses({teszt1.osztály, teszt2.osztály…})

A fenti annotációkkal a tesztcsomag összes osztálya egyesével elkezd végrehajtódni. Maga a tesztcsomag osztálya üres marad: csak az annotációk tárolója, és a futtató ezeket az annotációkat olvassa, hogy eldöntse, mit hajtson végre.

A Test Suite és a Test Runner létrehozásának lépései

Az alábbi négy lépésben felépíthető a legkisebb ténylegesen futó osztálycsomag: két hagyományos tesztosztály, egy osztálycsomag, amely elnevezi őket, és egy futtató, amely egy main metódusból indítja el a csomagot.

Step 1) Hozz létre egy egyszerű tesztosztályt (pl. MyFirstClassTest), és adj hozzá egy metódust, amely a következővel van ellátva: @Teszt.

Az első osztály egyetlen üres tesztmetódust tartalmaz, ami elég annak bizonyítására, hogy a csomag elfogadja azt:

ElsőOsztályomTeszt osztály itt Eclipse egy @Test által annotált myFirstMethod deklarálása

Step 2) Hozz létre egy másik tesztosztályt a hozzáadáshoz (pl. MySecondClassTest), és hozz létre egy @Test annotációval ellátott metódust.

A második osztály pontosan ugyanazt az alakot követi, így a sorozatnak két különálló osztálya van, amelyeket össze kell vonni:

MySecondClassTest osztály Eclipse egy @Test által annotált mySecondMethod deklarálása

Step 3) Egy testSuite létrehozásához először annotálni kell az osztályt a @RunWith(Suite.class) és a @SuiteClasses(class1.class, class2.class…) metódusokkal.

Figyeljük meg, hogy a TestSuiteExample csomagosztály nem deklarál saját tesztmetódust – a két annotáció tartalmazza az összes információt:

TestSuiteExample, @RunWith(Suite.class) megjegyzésekkel ellátva, és @SuiteClasses MyFirstClassTest és MyMásodikOsztályTest elnevezéssel ellátva

Step 4) Hozz létre egy Test Runner osztályt a tesztkészletünk futtatásához az alábbiak szerint:

A futó egy sima Java egy fő metódussal rendelkező osztály, amely átadja a suite osztályt a következőnek: JUnitCore:

Tesztfuttató osztály hívása JUnitCore.runClasses a TestSuiteExample-ben és a hibalista kinyomtatása

Code Magyarázat:

  • Code 8 vonal: A Test osztály main metódusának deklarálása, amely futtatni fogja a következőt: JUnit teszt.
  • Code 9 vonal: Tesztesetek végrehajtása a következő használatával: JUnitCore.runClasses, amely paraméterként fogadja a tesztosztály nevét (a fenti példában a 3. lépésben látható TestSuiteExample.class-t használjuk).
  • Code 11 vonal: Az eredmény feldolgozása egy for ciklus segítségével és a sikertelen eredmény kinyomtatása.
  • Code 13 vonal: A sikeres eredmény kinyomtatása.

output: Itt látható a kimenet, amely egy sikeres tesztet mutat hibák nélkül trace az alábbiak szerint:

Eclipse JUnit jelentések megtekintése 2/2-ben fut nulla hibával és nulla meghibásodással a TestSuiteExample számára

A zöld sáv megerősíti, hogy mire való egy csomag: egy indítás, egy eredménymegtekintés, és mindkét osztály a csomagcsomópont alatt jelenik meg, nem pedig két külön futtatásban.

JUnit Test Suite példa

Vegyünk egy összetettebb példát, amelyben a lakosztályon belüli osztályok valójában érvényesíteni valamit egy üres metódus tárolása helyett.

JunitTest.java

A JunitTest.java egy egyszerű osztály, amely a következővel van annotálva: @RunWith és a @Lakosztály annotációk. A csomagban tetszőleges számú osztályt megadhat paraméterként, az alábbiak szerint:

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 egy tesztosztály, amelynek tesztmetódusai egy üzenetet nyomtatnak ki, az alábbiak szerint. Ezt az osztályt a fent említett osztály egy csomagtagjaként fogod használni. Egy segédosztályra támaszkodik, amelynek neve JUnitÜzenet, amely ugyanabban a csomagban máshol van definiálva, és itt nem kerül reprodukálásra.

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 egy másik tesztosztály, hasonló a következőhöz: SuiteTest1.java, amelynek van egy tesztmetódusa az alább megadott üzenet kinyomtatására. Ezt az osztályt egy csomag tagjaként fogod használni a 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);							
    }		

}		

teljesítmény

A végrehajtás után JunitTest.java, amely egy olyan csomagot tartalmaz, amely a következőt tartalmazza: SuiteTest1.java és a SuiteTest2.java, az alábbi kimenetet kapod. A konzol kinyomtatja mindkét osztály által létrehozott üzeneteket:

Eclipse A konzol, amely a JunitTest befejezése után mindkét csomagosztály kinyomtatott üzeneteit mutatja

Az JUnit A nézet ugyanazt a futtatást rögzíti, mint három sikeres tesztmetódus, amelyek a csomagosztály alá vannak csoportosítva:

Eclipse JUnit jelentések megtekintése JunitTest 3/3-as zöld futtatása kibontott SuiteTest1 és SuiteTest2-vel

Jegyzet: A példában szereplő konzolcímkék kereszteződnek – a SuiteTest1 által kinyomtatott karakterlánc „Suite Test 2”, a SuiteTest2 által kinyomtatott pedig „Suite Test 1”. Az eredeti listák változatlanul kerülnek reprodukálásra, így a címkék úgy maradnak, ahogyan a szerző írta őket; olvassa el az osztály nevét a következőben: JUnit a nyomtatott címke helyett a nézetet, amikor a kimenetet a forráshoz illeszti.

Hogyan hozzunk létre egy tesztcsomagot? JUnit 5

JUnit Az 5-ös verzió teljesen eltávolítja a futtatókat, így a @RunWith(Suite.class) nem létezik az org.junit.jupiter csomagokban. A csomagok átkerültek ide: JUnit Platform, amely egy különálló, úgynevezett tárgyban szállítja őket junit-platform-suite-engineAdd hozzá ezt a függőséget, majd annotálj egy osztályt a @Suite paraméterrel és az egyik szelektor annotációval.

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
}

A szelektor annotációi az egyetlen @SuiteClasses listát egy kisebb opciócsaláddal helyettesítik:

Jegyzet Amit kiválaszt
@SelectClasses Egyenként elnevezett tesztosztályok, a @SuiteClasses közvetlen helyettesítői.
@SelectPackages Minden tesztosztály a megnevezett csomagban és annak összes alcsomagjában.
@IncludeClassNamePatterns Egy reguláris kifejezés szűrő alkalmazva a kijelölés felett.
@SuiteDisplayName Egy olvasható név, amely a jelentésben az osztálynév helyett jelenik meg.

Két további különbség számít a gyakorlatban. JUnit Az 5-ös suite osztály deklarálhatja a @BeforeSuite és @AfterSuite metódusokat, amelyek egyszer futnak le az egész suite-en, és a JUnit A fenti 4. példa továbbra is lefut a következőn: JUnit A platform a vintage motoron keresztül fut, így az ezen az oldalon található eredeti kódot nem kell átírni a folyamatos működéshez.

Előnyei és korlátai JUnit Teszt lakosztályok

A lakosztály egy csoportping mechanizmus, nem egy tesztelési keretrendszer sajátja, és ez formálja azt is, hogy miben csinálja jól, és hol válik egyre kevésbé hasznossá.

Előnyök

  • Egyetlen indítás kapcsolódó osztályokat futtat együtt, tehát egy füstkészlet vagy egy regresszió A set egyetlen paranccsal indítható el.
  • Az eredménynézet minden osztályt egyetlen csomagcsomópont alá csoportosít, ami megkönnyíti a megosztott hibák észrevételét.
  • A tagsági lista kódban található, így azt is ugyanúgy ellenőrzik és verziózzák, mint bármely más forrásfájlt.
  • Ugyanaz a csomagosztály elindítható egy IDE-ből, egy futtatókörnyezetből, például JUnitCore-ból, vagy egy építőeszközből.

korlátozások

  • A @SuiteClasses egy fixen kódolt lista, így egy új tesztosztály csendben kimarad, amíg valaki szerkeszti a csomagot.
  • A csomag nem vállal megrendelési garanciát az osztályok felsorolásának sorrendjén túl.
  • A tagosztályok között semmi sincs megosztva, így egy lakosztály nem helyettesíti a fixture-t vagy az alaposztályt.
  • A build eszközök már elnevezési konvenció alapján ismerik fel a tesztosztályokat, ami sok projektben redundánssá teszi a tesztcsomagokat.

Gyakori hibák létrehozásakor JUnit Test Suite

A legtöbb programcsomag-probléma egy rövid, nem túl hasznos üzenetet eredményez. A táblázat a valószínűleg előforduló üzeneteket az okukhoz és a megoldásukhoz rendeli.

Üzenet vagy tünet Okoz Rögzít
inicializálási hiba: Nincsenek futtatható metódusok Az osztály egy hagyományos tesztosztályként fut, de csak annotációkat tartalmaz. Add hozzá a @RunWith(Suite.class) függvényt, hogy a csomag futtatója vegye át az irányítást az alapértelmezett futtató helyett.
nem található szimbólum: osztálycsomag Hiányzik a Suite importálása. Importálja az org.junit.runners.Suite fájlt az org.junit.runner.RunWith fájllal együtt.
A lakosztály fut, de egy órát kihagynak A kurzust soha nem adták hozzá a @SuiteClasses listához. Add hozzá explicit módon az osztályt, vagy helyezd át a @SelectPackages-be a következőben: JUnit 5.
A fordító nem fogadja el az osztálynevet A @Runwith vagy a @suiteClasses karakterláncot rossz betűmérettel írta be. Java A megjegyzések megkülönböztetik a kis- és nagybetűket: a @RunWith és a @SuiteClasses értékeket pontosan kell írni.
Magában a suite osztályban lévő tesztek soha nem futnak le Egy @Test metódus hozzáadva a csomagtulajdonoshoz. Hagyd üresen a tárolót, és helyezd át a tesztmetódust egy tagosztályba.

Egyszer megírom a szvitet, és megtartomping pontos a valódi munka. Ha a lista eltér a lemezen lévő osztályoktól, a programcsomag zöld színt jelez, míg a lista egy része egységteszt a halmaz soha nem hajtódik végre, ez az egyik legcsendesebb hibamód a szoftver tesztelés.

GYIK

A csomag a felsorolás sorrendjében hajtja végre az osztályokat, de JUnit nem garantálja az egyes osztályokon belüli metódusok sorrendjét. Azok a tesztek, amelyek egy korábbi teszt lefuttatásától függenek, sérülékenyek, és át kell írni őket, hogy önmagukban is működjenek.

Igen. Egy modulcsomag osztály egy átlagos osztály a futtató szempontjából, így egy másik @SuiteClasses listán belüli elnevezése beágyazza a modulcsomagokat. A beágyazás hasznos egy felső szintű regressziós csomag esetében, amely kisebb modulcsomagokból épül fel.

A mesterséges intelligencia asszisztensek beolvassák a lemezen lévő tesztosztályokat, összehasonlítják azokat a @SuiteClasses listával, és megjelölik a soha nem hozzáadott osztályokat. Emellett klaszterezik az ismétlődő hibákat. trackiváltó ok alapján, ami lerövidíti a triázst, miután egy lakosztály egyszerre sok vöröset jelent.

Másodpilóta gyorsan írja ki az annotációpárt, de gyakran keveredik JUnit 4 és JUnit 5 importálás ugyanabban a fájlban. Ellenőrizd, hogy az org.junit.runners.Suite és az org.junit.platform.suite.api.Suite soha nem szerepelnek együtt, mert csak az egyikük egyezik a futtatóval.

Adja hozzá a junit-platform-suite-engine ágat a teszt hatóköréhez. A @Suite és @SelectClasses annotációk a junit-platform-suite-api ágban találhatók, amelyet a motor műterméke tranzitívan kér le, így egyetlen függőség általában elegendő.

Általában nem. A Surefire és a Gradle A tesztfeladat már a minták elnevezésével fedezi fel a tesztosztályokat, és futtatja mindet. Egy tesztcsomagot akkor érdemes írni, ha egy elnevezett részhalmazt, például egy füsthalmazt szeretnénk, amely kisebb, mint a teljes futtatás.

A futtató inicializálási hibát jelez az adott tagra vonatkozóan, kijelentve, hogy nem található futtatható metódus, és a teljes csomag sikertelenként van megjelölve. Távolítsa el a bejegyzést, vagy adjon hozzá egy @Test metódust az osztályhoz.

Ne egy szelektorlistán belül. Tartsa meg a JUnit 4 osztály a veterán motoron, és válaszd ki őket egy JUnit 5 db-os csomag, így mindkét motor ugyanazon a terhelésen működik JUnit Platformindítás annotációcsaládok keverése nélkül.

Foglald össze ezt a bejegyzést a következőképpen: