- COMP.CS.140
- 11. Toimiva ohjelma
- 11.1 (Yksikkö)testaus
- 11.1.3 Testikehys JUnit
Testikehys JUnit¶
Yksikkötestit kirjoitetaan sujuvimmin testikehystä käyttäen.
Javalle yksi tällainen on JUnit, joka on tarkoitettu testivetoiseen ohjelmistokehitykseen.
JUnitin uusin versio, JUnit 5, sijaitsee pakkauksessa org.junit.jupiter
.
Aiemmat versiot JUnit 4 ja JUnit 3 sijaitsivat vastaavasti pakkauksissa org.junit
ja junit.framework
.
JUnitin käyttöohjeet löydät verkosta: JUnit User Guide.
NetBeans tarjoaa suoraan JUnitin osana IDEä. Visual Studio Code myös tukee JUnitia Java Test Runner laajennuksen, joka asentuu oletuksena osana Java Extension Packia.
JUnitin testikehys on Java olio.
Testiluokan koodissa jokainen testimetodi annotoidaan @Test
annotaatiolla.
Tarvittaessa metodi voidaan määritellä ajettavaksi ennen tai jälkeen jokaisen tai kaikkien testimetodien
annotaatioilla @BeforeEach
(tai @AfterEach
) ja vastaavasti @BeforeAll
(tai @AfterAll
).
Lista JUnitin annotaatioista.
NetBeans luo JUnit testikoodin Javan luokkatiedostolla valikosta Tools->Create/Update Tests. Testiluokan perusrakenne on:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class MyClassTest {
@BeforeAll
public static void setUpClass() throws Exception {
// Toimenpiteet, jotka suoritetaan ennen ensimmäistä testiä
}
@BeforeEach
public void setUp() throws Exception {
// Toimenpiteet, jotka suoritetaan ennen jokaista testiä
}
@Test
public void testMethod() {
// Koodi methodin testaamiseksi
}
@AfterEach
public void tearDown() throws Exception {
// Toimenpiteet, jotka suoritetaan jokaisen testin jälkeen
}
@AfterAll
public static void tearDownClass() throws Exception {
// Toimenpiteet, jotka suoritetaan viimeisen testin jälkeen.
}
}
Lisäksi voidaan määritellä testien ajamiselle erilaisia ehtoja, testejä voidaan parametrisoida, määrittää ajettavaksi tietyssä järjestyksessä, määrittää ajettavaksi haluttu määrä kierroksia jne.
Esimerkki Date
-luokkaa testaavasta testiluokasta:
public class DateTest {
@Test
public void testGetYear() {
// tulostetaan testattavan metodin nimi
System.out.println("getYear");
// luodaan testattava luokan instanssi
Date instance = new Date(2022, 2, 28);
// määritellään odotettu tulos
int expResult = 2022;
// haetaan testi-instanssin tilan arvo
int result = instance.getYear();
// tutkitaan vastaako haettu tila odotettua tulosta
// jos eivät, assertEquals heittää AssertionErrorin
assertEquals(expResult, result);
}
@Test
public void testGetMonth() {
System.out.println("getMonth");
Date instance = new Date(2022, 2, 28);;
int expResult = 2;
int result = instance.getMonth();
assertEquals(expResult, result);
}
@Test
public void testGetDay() {
System.out.println("getDay");
Date instance = new Date(2022, 2, 28);;
int expResult = 28;
int result = instance.getDay();
assertEquals(expResult, result);
}
@Test
public void testToString() {
System.out.println("toString");
Date instance = new Date(2022, 2, 28);;
String expResult = "28.02.2022";
String result = instance.toString();
assertEquals(expResult, result);
}
@Test
public void whenExceptionThrown() {
System.out.println("whenExceptionThrown");
Exception exception = assertThrows(DateException.class, () -> {
new Date(2022, 2, 29);
});
String expectedMessage = "Illegal date 29.02.2022";
String actualMessage = exception.getMessage();
System.out.println(actualMessage);
assertTrue(actualMessage.contains(expectedMessage));
}
// Tehdään parametrisoitu testi
// jolle annetaan syötetiedot intProvider-metodilla
@ParameterizedTest
@MethodSource("intProvider")
void testLegalDates(int year, int month, int day) {
System.out.println("isLegalDate");
assertTrue(Date.isLegalDate(day, month, year));
}
// Testin parametrit streamina palauttava metodi
// Streamin ohella mikä tahansa säiliö olisi sallittu, esim. List.
static Stream<Arguments> intProvider() {
return Stream.of(
arguments(2014, 2, 14),
arguments(2020, 5, 30)
);
}
}