CodeGym /Java blog /Véletlen /Egységtesztelés Java nyelven a JUnit segítségével
John Squirrels
Szint
San Francisco

Egységtesztelés Java nyelven a JUnit segítségével

Megjelent a csoportban

Mi az egységtesztelés a Java-ban?

Mielőtt belevágnánk a JUnit Java nyelven való tanulásába, tekintsük át röviden, mi az egységtesztelés, és miért olyan népszerű (ha már ismeri ezt a dolgot, ugorjon a „Hogyan írhatok JUnit tesztet Java nyelven?” című részhez). A Java egységtesztelése sokkal hatékonyabbá és könnyedebbé teszi a nagyszabású szoftverfejlesztést. Segíthet mind az egyéneknek, mind a csapatoknak számtalan órát lefaragni a hibakeresésből, és rendkívül egyszerűsíti az együttműködési folyamatot. Egységtesztelés Java nyelven a JUnit segítségével - 1

https://junit.org/junit4/

Az egységtesztelés lényege a következő: írjon atomteszteket az egyes jellemzőkről (úgynevezett egységtesztek), majd a tesztelés és a korábbiak működésének biztosítása után lassan adjon hozzá további jellemzőket. Ez egy rendkívül egyszerű, de erőteljes ötlet. Példaként arra, hogyan nézhet ki ez a folyamat, képzelje el, hogy egy virtuális tudományos számológépet épít. +A látszólagos aritmetikai operátorok ( , -, x, ) mellett %ez a számológép olyan fejlett funkciókkal is rendelkezik, amelyek működéséhez más alszolgáltatások is szükségesek. A kitevők kiszámításához a számológépnek tudnia kell helyesen szorozni. Tehát a számológép összeállításának és tesztelésének egységtesztelési megközelítése a következő lenne:
  • Írjon összeadási függvényt. Óvatosan tesztelje, cserélje ki, ismételje meg, amíg működik.
  • Ugyanezt tegye a kivonási, szorzási, osztási függvényeknél.
  • Használja ezeket az alapoperátorokat fejlettebb operátorfüggvények, például kitevők írásához, majd tesztelje ezeket a függvényeket is.
Ez biztosítja, hogy azok a szolgáltatások, amelyek más kisebb részszolgáltatásokból épülnek fel, nemcsak önmagukban megfelelően működnek, de nem tartalmaznak hibás részszolgáltatásokat. Például, ha a kitevőfüggvényt tesztelem, és valami elromlik, tudom, hogy a hiba valószínűleg nem a szorzási alfunkcióban van, mert a szorzófüggvényt már alaposan tesztelték. Ez nagymértékben kiküszöböli a kód teljes mennyiségét, amelyet vissza kell nyomnom és megvizsgálnom, hogy megtaláljam a hibát. Remélhetőleg ez a triviális példa világossá teszi, hogyan épül fel az egységtesztelés körüli gondolkodási folyamat. De hogyan kapcsolódik az egységtesztelés a szoftverfejlesztési folyamat többi részéhez? Mi van, ha még összetettebb funkciókkal rendelkezik, amelyeknek együtt kell működniük és kommunikálniuk kell? Az egységteszt nem elegendő annak biztosítására, hogy az ilyen összetett funkciók megfelelően működjenek együtt. Valójában ez csak az első lépése a szoftvertesztelés négy szintjének (nagybetűket használok, mert az iparági szabványra vagy a szoftvertesztelés leggyakoribb megközelítésére utalok). Az utolsó három lépés azIntegrációs tesztelés , rendszertesztelés és elfogadási tesztelés. Valószínűleg ezek mind pontosan azt jelentik, amit Ön gondol, de hadd tisztázzam: az integrációs teszteléssel biztosítjuk, hogy a fent említett „összetett funkciók” megfelelően kölcsönhatásba léphessenek egymással. (pl. annak biztosítása, hogy a számológép képes kezelni a "3 + 7 * 4 - 2" értékeket). A rendszertesztelés egy adott rendszer általános kialakítását teszteli; Egy termékben gyakran több, összetett funkciókból álló rendszer működik együtt, ezért ezeket rendszerekbe kell csoportosítani és egyenként tesztelni. (pl. ha grafikus számológépet építene, először fel kell építenie az aritmetikai „rendszert” a számok kezelésére, addig tesztelnie kell, amíg rendeltetésszerűen működik, majd felépítenie és tesztelnie kell a grafikus „rendszert” a visszavonás kezelésére, mint pl. az aritmetikai rendszerből épülne fel). Az elfogadási tesztelés felhasználói szintű tesztelés; azt vizsgálja, hogy az összes rendszer képes-e szinkronban dolgozni egy késztermék létrehozásához, amely készen áll a felhasználók általi elfogadásra (pl. a számológépet tesztelő felhasználók). A szoftverfejlesztők néha figyelmen kívül hagyhatják a folyamat ezen utolsó lépését, mivel a vállalatok gyakran más alkalmazottakkal külön telepítik a felhasználói (béta) teszteket.

Hogyan írhatok JUnit tesztet Java nyelven?

Most, hogy tisztább elképzelése van az egységteszt előnyeiről és korlátairól, vessünk egy pillantást néhány kódra! A JUnit nevű népszerű Java tesztelési keretrendszert fogjuk használni (egy másik népszerű a TestNG, amit te is használhatsz, ha akarod. Szintaktikailag nagyon hasonlóak; a TestNG-t a JUnit ihlette). A JUnit letölthető és telepíthető innen . Ennél a példakódnál folytatjuk a korábban említett „tudományos számológép” példát; nagyon egyszerű körbetekerni a fejét, és a tesztkód rendkívül egyszerű. A hagyományos gyakorlat az, hogy minden egyes osztályhoz külön tesztosztályt írunk, így mi ezt fogjuk tenni. Tételezzük fel, hogy ezen a ponton van egy Math.javafájlunk az összes matematikai függvényrel (beleértve Math.adda ), és írunk egyMathTests.javafájlt ugyanabban a csomagban. Most állítsuk be az import utasításokat és az osztály törzsét: (LEHETSÉGES JUnit INTERJÚ KÉRDÉS: Megkérdezhetik, hogy hova helyezze el a JUnit tesztet, és hogy importálnia kell-e a forrásfájljait. Ha a tesztosztályokat ugyanabba a csomagba írja, mint fő osztályait, akkor a tesztosztályban nincs szükség importálási utasításokra a forrásfájlokhoz. Ellenkező esetben ügyeljen arra, hogy a forrásfájlokat importálja!)

import org.junit.jupiter.Test;    //gives us the @Test header
import static org.junit.jupiter.api.Assertions.assertEquals; //less typing :) 

public class MathTests {
	//...
}
Az első import utasítás megadja a @Testfejlécet. @TestKözvetlenül minden tesztfüggvény definíció tetejére írjuk a " " jelet, hogy a JUnit tudja, hogy ez egy egyedi egységteszt, amely külön is futtatható. A későbbiekben megmutatom, hogyan futtathat konkrét egységteszteket ezzel a fejléccel. A második import utasítás megkímél minket a gépeléstől. Az elsődleges JUnit függvény, amelyet a függvényeink tesztelésére használunk, a to Assert.assertEquals(), amely két paramétert (tényleges értéket és várható értéket) vesz fel, és biztosítja azok egyenlőségét. Ennek a második importálási utasításnak köszönhetően egyszerűen begépelhetjük a " assertEquals(..." szót, ahelyett, hogy minden alkalommal meg kellene adni, hogy melyik csomag része. Most írjunk egy nagyon egyszerű tesztesetet annak ellenőrzésére, hogy 2 + 2 valóban 4!

import org.junit.jupiter.Test; // gives us the @Test header
import static org.junit.jupiter.api.Assertions.assertEquals; // less typing :) 


public class MathTests {
	@Test
	public void add_twoPlusTwo_returnsFour(){
	final int expected = 4;
	final int actual = Math.add(2, 2);
	assertEquals(“2+2 is 4”, actual, expected);
	}
}
Tekintsük át a tesztfüggvények öt sorát, és mit csinálnak: 5. sor: Ez @Testa fejléc azt határozza meg, hogy az alábbi függvénydefiníció add_twoPlusTwo_returnsFour()valóban egy tesztfüggvény, amelyet a JUnit külön is futtathat. 6. sor: Ez a tesztesetünk függvényaláírása. A tesztesetek mindig nagyon egyediek; csak egy konkrét példát tesztelnek, például 2+2=4. A tesztesetek elnevezése szokásos „ [function]_[params]_returns[expected]()”, ahol [function]a tesztelt függvény neve, [params]a tesztelt konkrét példaparaméterek, és [expected]a függvény várható visszatérési értéke. A tesztfüggvények visszatérési típusa szinte mindig ' void', mert az egész függvény lényege a futásassertEquals, amely akkor jelenik meg a konzolon, ha a teszt sikeres volt vagy sem; nem kell más adatot visszaküldeni sehova. 7. sor: Deklaráljuk a finalvisszatérési típusú ' ' változót Math.add (int), és megegyezés szerint 'várható' nevet adunk neki. Értéke a várt válasz (4). 8. sor: Deklaráljuk a finalvisszatérési típusú ' ' változót Math.add (int), és megegyezés szerint 'tényleges' nevet adunk neki. Ennek értéke az eredménye Math.add(2, 2). 9. sor: Az arany vonal. Ez az a vonal, amely összehasonlítja a tényleges és a várt, és csak akkor felel meg a teszten, ha egyenlők. Az első átadott paraméter „2+2 az 4” a tesztfunkció leírása.

Mi van, ha a függvényem kivételt jelent?

Ha a konkrét tesztpéldának kivételt kell tennie ahelyett, hogy azt állítaná, hogy a tényleges és a várható érték egyenlő, akkor a JUnit ezt tisztázza a fejlécben @Test. Nézzünk egy példát az alábbiakban. Feltételezve, hogy van egy függvényünk a Math.javanevű függvényben Math.divide, meg akarunk győződni arról, hogy a bemenetek nem oszthatók 0-val. Ehelyett, ha megpróbálunk Math.divide(a, 0)bármilyen 'a' értéket hívni, kivételt ( ArithmeticException.class) kell dobni. A fejlécben így adjuk meg:

import org.junit.jupiter.Test; // gives us the @Test header
import static org.junit.jupiter.api.Assertions.assertEquals; // less typing :) 


public class MathTests {
	@Test (expectedExceptions = ArithmeticException.class)
	public void divide_byZero_throwsException() throws ArithmeticException{
	Math.divide(1, 0);
	}
}
Egynél több kivételt expectedExceptionsis megadhat a következőhöz:

expectedException = {FirstException.class, SecondException.class, … }

Hogyan futtathatom a JUnit tesztjeimet Java nyelven?

A JUnit hozzáadása az IntelliJ-hez: https://stackoverflow.com/questions/19330832/setting-up-junit-with-intellij-idea A projektet a szokásos módon futtathatja. A tesztosztály összes tesztjének futtatása ábécé sorrendben történik. A JUnit 5-ben egy címke hozzáadásával prioritást adhat a tesztekhez @Order. Egy példa:

@TestMethodOrder(OrderAnnotation.class)
public class Tests {
…
@Test
@Order(2)
public void a_test() { … }

@Test
@Order (1)
public void b_test() { … }
…
}
Annak ellenére, hogy ábécé sorrendben és a kódban a_test()előtte van , itt fog futni , mert az 1 sorrendben a 2 előtt áll. Tehát nagyjából ennyi a JUnit alapjairól. Most pedig nézzünk meg néhány gyakori JUnit-interjúkérdést, és tudjunk meg többet a JUnitről az út során! b_test()b_test()a_test()

JUnit interjúkérdések (további információ)

Itt összegyűjtöttem a legnépszerűbb JUnit interjúkérdéseket. Ha van hozzáfűznivalója - nyugodtan tegye ezt az alábbi megjegyzésekben. K: Milyen módszert hívhat meg a tesztmódszerben a teszt automatikus sikertelenségéhez? V: fail (“hiba leírása itt!”); K: Ön egy kutyaosztályt tesztel; egy Dog objektum teszteléséhez példányosítani kell, mielőtt teszteket futtathatna rajta. Tehát írsz egy setUp() függvényt a kutya példányosítására. Ezt a funkciót csak egyszer szeretné futtatni az egész tesztelés során. Mit kell elhelyezni közvetlenül a setUp() függvény aláírása fölé, hogy a JUnit tudja, hogy futtassa-e a setUp()-ot a tesztek futtatása előtt? V: @BeforeClass (@BeforeAll in JUnit 5) K:Mi legyen a fent leírt setUp() függvény függvényaláírása? V: nyilvános statikus üresség. A @BeforeClass (@BeforeAll a JUnit 5-ben) vagy az @AfterClass (@AfterAll a JUnit 5-ben) függvénynek statikusnak kell lennie. K: Befejezte a Kutya osztály tesztelését. Írja a void tearDown() függvényt, amely minden teszt után megtisztítja az adatokat és információkat nyomtat a konzolra. Azt szeretné, hogy ez a funkció minden egyes teszt után fusson. Mit kell közvetlenül a tearDown() függvény aláírása fölé tenni, hogy a JUnit tudja, hogy minden teszt futtatása után le kell futnia a tearDown() függvénynek? V: @After (@AfterEach in JUnit 5)
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION