A JUnit egy szabványos keretrendszer moduláris teszteléshez a Java és Kotlin ökoszisztémában, amelyet Android-fejlesztésben használnak üzleti logika ellenőrzésére izolált komponensek szintjén. A keretrendszer annotációk, assertion metódusok és Test Runner készletét biztosítja a tesztek automatikus felismeréséhez és végrehajtásához. A JUnit.org adatai szerint a könyvtár továbbra is a legnépszerűbb megoldás az egységtesztelésre a JVM ökoszisztémában: a Java projektek több mint 70%-a használja a JUnit valamelyik változatát.
Főbb pontok
A JUnit egy nyílt forráskódú keretrendszer ismételhető egységtesztek írásához és futtatásához Java és Kotlin nyelven. Része a xUnit ökoszisztémának — a Kent Beck és Erich Gamma által megalkotott architektúrán alapuló keretrendszerek családjának — és ez a szabványos tesztelőeszköz az Android Studio-ban és az IntelliJ IDEA-ban.
A JUnit fő feladata egy kis kódrészlet (metódus, osztály) elkülönítése és viselkedésének ellenőrzése ellenőrzött körülmények között. A tesztek szokásos Java/Kotlin osztályokként íródnak annotációkkal, a keretrendszer pedig gondoskodik a tesztek felismeréséről, életciklusuk kezeléséről és a végrehajtási statisztikák gyűjtéséről.
A JUnit első változata 1997-ben jelent meg és gyökeresen megváltoztatta a fejlesztési szemléletet, népszerűsítve a Tesztvezérelt fejlesztés (TDD) gyakorlatait. Ma a JUnit 5 (Jupiter) a jelenlegi változat, teljesen útervezve moduláris architektúrával, Java 8+ és bővítmények támogatásával.
A JUnit végrehajtásának mechanizmusa a Test Runner mintán alapul, amely beolvassa a classpath-t, megtalálja a @Test annotációval ellátott metódusokat, létrehozza a tesztosztály példányát és meghatározott sorrendben futtatja a metódusokat. A Test Runner kezeli az életciklust: BeforeAll → BeforeEach → Test → AfterEach → AfterAll hívás.
A JUnit minden tesztmetódust külön osztálypéldányba csomagol, ami elkülönítést garantál a tesztek között. Ez azt jelenti, hogy az osztály mezői nem őrzik meg az állapotot a különböző @Test metódusok között — minden teszt tiszta objektummal kezdődik.
A legegyszerűbb teszt a JUnit-ban egy @Test annotációval ellátott metódusként néz ki, amelyben a tesztelt kód meghívásra kerül, és az eredmény egy assertion segítségével kerül ellenőrzésre. Ha az assertion nem megy át — a teszt sikertelennek tekintendő, és a JUnit hibát jelent.
@Test
void additionShouldReturnCorrectSum() {
var calculator = new Calculator();
var result = calculator.add(2, 3);
assertEquals(5, result);
}
A Test Runner automatikusan megtalálja az ilyen metódust, futtatja és jelenti az eredményt. Ha a metólus nem dob kivételt — a teszt sikeres (green). Ha az assertion nem működik — a teszt megbukik (red).
A JUnit annotációi meghatározzák, hogy a tesztkód mikor és hogyan kerüljön végrehajtásra. A JUnit 5-ben az annotációk a org.junit.jupiter.api csomagban találhatók és lefedik az összes fázist: adatok előkészítése, teszt végrehajtása, erőforrások felszabadítása.
| Annotáció | Cél | Végrehajtás |
|---|---|---|
| @Test | Jelöli a tesztmetódust | Egyszer hívásonként |
| @BeforeEach | Előkészítés minden teszt előtt | Minden @Test előtt |
| @BeforeAll | Egyszeri osztályinicializálás | Egyszer az összes teszt előtt |
| @AfterEach | Tisztítás minden teszt után | Minden @Test után |
| @AfterAll | Egyszeri osztálylezárás | Egyszer az összes teszt után |
| @DisplayName | Ember által olvasható tesztnév | Dekoráció |
Nézzünk meg egy teljes tesztosztályt helyes életciklussal. A setUp metódus minden teszt előtt létrehoz egy friss Calculator példányt, a tearDown pedig felszabadítja az erőforrásokat — például bezárja a fájlleírókat vagy az adatbázis-kapcsolatokat.
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
void subtractionShouldReturnCorrectResult() {
int result = calculator.subtract(10, 4);
assertEquals(6, result);
}
@AfterEach
void tearDown() {
calculator.reset();
}
}
Az Assertion-ök statikus metódusok, amelyek összehasonlítják a tényleges eredményt a várttal, és kivételt dobnak, ha nem egyeznek. A JUnit 5 a org.junit.jupiter.api.Assertions osztályt kínálja több mint 25 metódussal különböző ellenőrzési forgatókönyvekhez — az egyszerű értékösszehasonlítástól az időtúllépések és csoportos assertion-ök ellenőrzéséig.
Az assertThrows metódus külön figyelmet érdemel — lehetővé teszi annak ellenőrzését, hogy a kód helyesen kezeli a hibás helyzeteket — nullával osztás, null átadása, határértékek túllépése.
@Test
void divisionByZeroShouldThrowException() {
Calculator calc = new Calculator();
ArithmeticException exception = assertThrows(
ArithmeticException.class,
() -> calc.divide(10, 0)
);
assertEquals("Cannot divide by zero", exception.getMessage());
}
A paraméterezett tesztek lehetővé teszik ugyanazon tesztmetódus futtatását különböző argumentumkészletekkel. A JUnit 5-ben erre a @ParameterizedTest annotáció szolgál egy adatforrással kombinálva — @ValueSource, @CsvSource, @MethodSource vagy @EnumSource.
Ez a megközelítés drasztikusan csökkenti a kódismétlést: tíz azonos teszt helyett különböző értékekre egy paraméterezett metódust írunk. A Google Testing Blog szerint a paraméterezés 40–60%-kal csökkenti a tesztkód mennyiségét a lefedettség elvesztése nélkül.
A @CsvSource annotáció több sort küld a tesztnek vesszővel elválasztva. Minden sor egy tesztfuttatásnak felel meg. A JUnit automatikusan konvertálja a sztring értékeket a szükséges típusokra: int, long, String és mások.
@ParameterizedTest
@CsvSource({
"1, 1, 2",
"2, 3, 5",
"10, 20, 30",
"-1, 1, 0"
})
void additionWithMultipleInputs(int a, int b, int expected) {
assertEquals(expected, a + b);
}
Amikor a bemeneti adatok összetettebbek, mint az egyszerű számok vagy sztringek, a @MethodSource-t használjuk. Ez egy statikus metódusra hivatkozik, amely argumentumok Stream-jét adja vissza — például Arguments Stream vagy User objektumok Stream-je a DAO réteg teszteléséhez.
Az Android-fejlesztésben a JUnit-ot az AndroidX Test-tel együtt használják, amely bővítményeket biztosít az Activity, Content Provider és más Android komponensek teszteléséhez. A JUnit felel az egységteszteért (unit tests), amelyek a JVM-en futnak emulátor nélkül, az AndroidX Test pedig az eszközön futó instrumentális tesztekért.
A JUnit 5 Android-projektbe történő csatlakoztatásához elég a org.junit.jupiter:junit-jupiter függőség hozzáadása a modul szintű build.gradle-ben. Az AGP Gradle plug-in támogatja a JUnit 5 tesztek futtatását a JVM-en a szabványos Test Runneren keresztül.
// build.gradle.kts
android {
testOptions {
unitTests.isIncludeAndroidResources = true
}
}
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.11.0")
testImplementation("androidx.test:core-ktx:1.6.1")
}
A gyakorlatban a JUnit-ot leggyakrabban a ViewModel és tárolók tesztelésére használják — azon rétegekért, amelyek nem igényelnek Android kontextust vagy emulátort. Egy ilyen teszt ezredmásodpercek alatt végrehajtható és százszor is lefuttatható időveszteség nélkül.
A JUnit 5 (Jupiter) nem csupán új változat, hanem teljesen útervezett platform, három modulra bontva: JUnit Platform (tesztek futtatása a JVM-en), JUnit Jupiter (API tesztek írásához) és JUnit Vintage (visszafelé kompatibilitás a JUnit 4-gyel). Ez a modularitás lehetővé teszi különböző Test Engine-ek csatlakoztatását — például Spek a Kotlinhoz vagy TestNG.
| Jellemző | JUnit 4 | JUnit 5 |
|---|---|---|
| Csomag | org.junit | org.junit.jupiter |
| Alap annotáció | @Test (junit.framework-ból) | @Test (org.junit.jupiter.api-ból) |
| Before/After | @Before, @After, @BeforeClass | @BeforeEach, @AfterEach, @BeforeAll |
| Parameterized | @RunWith(Parameterized.class) | @ParameterizedTest + @ValueSource |
| Extension | @Rule, @ClassRule | @ExtendWith, rugalmasabb API |
| Java min | Java 5 | Java 8+ |
A JUnit 4-ről JUnit 5-re történő migráció nem igényli az összes teszt újraírását — elég csatlakoztatni a JUnit Vintage Engine-t, és a régi tesztek továbbra is működni fognak. Az új teszteket érdemes JUnit 5-ben írni, hogy kihasználhassuk a bővítményeket, a lambda kifejezéseket az assertion-ökben és a beépített paraméterezési támogatást.
Gyakran ismételt kérdések
A JUnit keretrendszer tesztek írásához és futtatásához, míg a Mockito könyvtár mock objektumok létrehozásához. Együtt használják őket: a JUnit kezeli a teszt végrehajtását, a Mockito pedig helyettesíti a tesztelt osztály függőségeit.
Igen, a JUnit 5 teljesen kompatibilis az Android-projektekkel. Az egységtesztekhez elég a junit-jupiter függőség hozzáadása a build.gradle-ben. Az instrumentális tesztek továbbra is az AndroidX Test Runneren keresztül működnek.
Minimum egy @Test annotáció a metódus előtt elegendő. Inicializáláshoz és tisztításhoz a @BeforeEach és @AfterEach ajánlott, de nem kötelező.
A Test Runner a JUnit azon komponense, amely beolvassa a classpath-t, megtalálja a @Test annotációval ellátott metódusokat, létrehozza a tesztosztályok példányait és futtatja a teszteket. A JUnit 5-ben ezt a szerepet a JUnit Platform tölti be csatlakoztatott Test Engine-ekkel.
Használja az assertThrows(Class, Executable) metódust — ez elfogadja a várt kivétel típusát és egy lambdát a metódushívással. A JUnit ellenőrzi, hogy a kivétel tényleg dobásra került-e, és visszaadja azt további ellenőrzéshez.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is