JUnit #
@Testing
Allgemeines #
Unit testing kann sich beziehen auf
- eine Methode,
- eine Gruppe von Methoden oder
- eine Klasse
Test-Methoden sollten immer public
sein, da möglicherweise ein externes Framework darauf zugreifen muss.
@BeforeClass
- und @AfterClass
-Methoden müssen immer static
sein.
Exceptions testen. Bspw.: @Test(expected=NullPointerException.class) public void testArraySort_NullArray() { int[] numbers = {}; Arrays.sort(numbers); }
Performance Testing mit JUnit. Bspw.: @Test(timeout=1000) public void testSort_Performance(){ int array[] = {12,23,4}; for(int i=1; i<100000;i++) { array[0] = i; Arrays.sort(array); } }
Es macht Sinn, das Timeout nicht zu eng zu setzen, da die Tests auch in anderen Umgebungen (bspw. Testserver) ausgeführt werden, die möglicherweise ein anderes Hardware-Setting haben.
Parametrisierte Klassen werden verwendet, wenn die Test-Logik dieselbe ist, aber verschiedene Ein- und Rückgabewerte getestet werden sollen
- Test-Klasse muss mit
@RunWith(Parametrized.class)
annotiert werden - Eine statische Methode, welche mit
@Parameters
annotiert ist und eineCollection<>
zurückgibt (als Map mit Ein- und Rückgabe-Wert) - Ein Constructor, welcher als Parameter einen Eingabewert und den zugehörigen erwarteten Rückgabe-Wert entgegennimmt und diese Klassen-Members übergibt
- Verwendung der entsprechenden Klassen-Members in den
@Test
-Methoden
Bsp.: @RunWith(Parametrized.class) public class StringHelperParametrizedTest { StringHelper helper = new StringHelper();
private String input;
private String expectedOutput;
public StringHelperParametrizedTest(String input, String expectedOutput) {
this.input = input;
this.expectedOutput = expectedOutput;
}
@Parameters
public static Collection<String[]> testCondition() {
String expectedOutputs[][] = {
{ "AAD", "CD" },
{ "ACD", "CD" } };
return Arrays.asList(expectedOutputs);
}
@Test
public void testTruncateAInFirst2Positions() {
assertEquals(expectedOutput, helper.truncatedAInFirst2Positions(input));
}
}
Test Suites (Gruppe von Tests) sind Klassen, welche mit zwei Annotationen ausgestattet sind:
@RunWith(Suite.class)
(stellt@SuiteClasses
zur Verfügung)@SuiteClasses( {<erste_testklasse.class>, <zweite_testklasse.class> etc.}}
@Rule
: Anstelle von @RunWith(...)
, bspw. @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
Vorteil ist, dass mehrere Rules definiert werden können (im Gegenteil zu Runners). Es ist zu erwarten, dass Runners in zukünftigen Versionen von JUnit zugunsten von Rules an Wichtigkeit verlieren.
JUnit 5 #
JUnit 5 ist die aktuelle Version von JUnit und bringt gegenüber ihren Vorgängern einige tiefgreifende Änderungen mit sich. Wichtig ist dabei v.a. die Modularisierung des Frameworks: JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
- Die Platform dienst als Fundament für das Starten von Testframeworks auf der JVM.
- Jupiter ist die Kombination des neuen Programmierungs- und des neuen Erweiterungsmodels, um Tests und Erweiterungen zu schreiben.
- Vintage stellt eine
TestEngine
zur Verfügung, um Tests auszuführen, die auf JUnit 3 oder 4 beruhen.