Unit Test
R 2.0.0
Beschreibung
Die Basis für gute Unit-Test ist das Erfüllen des F.I.R.S.T-Prinzips:
-
Fast: Die Testausführung soll schnell sein, damit man sie möglichst oft ausführen kann. Je häufiger man die Tests ausführt, desto schneller bemerkt man Fehler und desto einfacher ist es, diese zu beheben.
-
Independent: Unit Tests sind unabhängig voneinander, damit man sie in beliebiger Reihenfolge, parallel oder einzeln ausführen kann.
-
Repeatable: Führt man einen Unit Test mehrfach aus, muss er immer das gleiche Ergebnis liefern.
-
Self-Validating: Ein Unit Test soll entweder fehlschlagen oder gut gehen. Diese Entscheidung muss der Test treffen und als Ergebnis liefern. Es dürfen keine manuellen Prüfungen nötig sein.
-
Timely: Man soll Unit-Tests vor der Entwicklung des Produktivcodes schreiben.
Das SetUp und TearDown bei Unit Tests
Häufig verwendet man in Testautomaten Testschritte, die am Ende eines Tests als „TearDown / After“ (Nachbearbeitung) markiert werden können. Diese Schritte sorgen dafür, dass der Test in einem definierten Endzustand verlassen wird, sodass der folgende Test mit deinem „Setup“ (Vorbereitung) einen sauberen Startzustand herstellen kann.
Im Allgemeinen fügen Sie alle erforderlichen Schritte in „SetUp / Before“ und alle Bereinigungsschritte in „TearDown / After“ hinzu. Sie erstellen diese Methode jedoch nur, wenn diese Schritte für jeden Test erforderlich sind. Wenn nicht, werden diese Schritte innerhalb der spezifischen Tests im Abschnitt "Anordnen" ausgeführt.
Beispiel in Java
In diesem Beispiel testen wir eine Rechteck-Klasse:
Rechteck.java
public class Rechteck {
private int a;
private int b;
public Rechteck(int a, int b) {
this.a = a;
this.b = b;
}
public float berechneUmfang() {
return 2 * a + 2 * b;
}
public float berechneInhalt() {
return a * b;
}
}
Ordnerstruktur
Allgemein empfehlen wir einen neuen Source-Ordner namens „test“ anzulegen und die ggf. vorhandene Paketstruktur zu übernehmen. Dies erhöht die Übersichtlichkeit und erleichtert die Testkoordination. In der folgenden Abbildung sieht man die neue Projekt-Struktur:
Der Komponententest zum Testen dieser Klasse sieht folgendermaßen aus (mit der Hilfe des Werkzeuges "JUnit"):
RechteckTest.java
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
// Diese Klasse testet die Implementierung zur "Task-ID: 1"
public class RechteckTest {
private static Rechteck myRechteck;
@BeforeClass
public static void create() {
// Test-Objekt erschaffen mit den Testwerten (Länge: 10 und Breite: 20)
myRechteck = new Rechteck(10, 20);
System.out.println("Seitenlängen wurden gesetzt, a=10 und b=20\n");
}
@Before
public void vor() {
// Diese Methode wird vor jedem Testfall ausgeführt
System.out.println("Möchten Sie die Werte ändern?");
}
@Test
public void TestUmfangsberechnung() {
// Testfall 1: Prüfung ob Umfangsberechnung stimmt
System.out.println("Umfangsberechnung = 60");
Assert.assertTrue(60 == myRechteck.berechneUmfang());
}
@Test
public void TestFlaecheninhaltsberechnung() {
// Testfall 2: Prüfung ob Flächeninhaltsberechnung stimmt
System.out.println("Flächeninhaltsberechnung = 200");
Assert.assertTrue(200 == myRechteck.berechneInhalt());
}
@After
public void nach() {
// Diese Methode wird nach jedem Testfall ausgeführt z.B. um einen bestimmten Zustand zu erreichen
System.out.println("Berechnung wurde zurückgesetzt\n");
}
@AfterClass
public static void delete() {
// Diese Methode wird am Ende der Test-Klasse ausgeführt z.B. zum aufräumen oder löschen von Rückständen
System.out.println("Testwerte wurden gelöscht");
}
}
Quellen
-
Wikipedia, Modultest, abgerufen am 13.02.2024