Eigenschaften guter Unit‑Tests
Dieser Beitrag ist eine Begriffserklärung zu Eigenschaften guter Unit‑Tests – inklusive Prüfungsfragen und Tags.
In a Nutshell
Gute Unit‑Tests sind korrekt, isoliert, schnell, aussagekräftig, wartbar und einfach durchführbar. Sie geben schnelles, verlässliches Feedback und ermöglichen sicheres Refactoring.
Kompakte Fachbeschreibung
1. Korrekt
Test überprüft das, was er prüfen soll – keine falschen Annahmen, keine zufälligen Ergebnisse.
2. Isoliert
Keine Abhängigkeiten zu externen Systemen (DB, Netzwerk, Dateisystem). Stattdessen Testdoubles (Stubs, Mocks, Fakes).
3. Schnell
Ausführung im Millisekunden‑Bereich, damit Hunderte Tests in Sekunden laufen können (CI‑Feedback).
4. Aussagekräftig
Klare Testnamen, verständliche Arrange/Act/Assert‑Struktur, präzise Assertions mit aussagekräftigen Fehlermeldungen.
5. Wartbar
Kein duplizierter Code (DRY), gemeinsame Hilfsbibliotheken, Refactoring‑sicher.
6. Einfach durchführbar
Ein Befehl startet alle Tests, keine manuelle Vorbereitung, deterministische Ergebnisse.
Prüfungsrelevante Stichpunkte
- AAA (Arrange, Act, Assert) als Struktur
- Testdoubles: Stub (vordefinierte Antworten) vs. Mock (Erwartungen prüfen)
- Naming:
methodName_condition_expectedResult - Edge Cases und Fehlerfälle explizit testen
- Keine „magischen“ Zahlen, Konstanten verwenden
- Assertions aussagekräftig (z.B.
assertEquals(expected, actual, message)) - Tests unabhängig machen (Reihenfolge egal)
- Deterministisch (kein Zufall, keine Zeitabhängigkeit)
Kernkomponenten
- Teststruktur (AAA)
- Testdoubles (Stub, Mock, Fake, Spy)
- Naming‑Konventionen
- Assertions (klare Fehlermeldungen)
- Testdaten (Factories, Builder)
- Isolation (keine externen Abhängigkeiten)
- Geschwindigkeit (ms‑Bereich)
- Unabhängigkeit (Reihenfolge egal)
- Determinismus (kein Zufall/Zeit)
- Wartbarkeit (DRY, Refactoring‑sicher)
Praxisbeispiel (Rabattberechnung)
// Naming: berechneRabatt_neukunde_standardartikel_erwartet0Prozent
@Test
public void berechneRabatt_neukunde_standardartikel_erwartet0Prozent() {
// Arrange
Kunde kunde = new Kunde(Kundentyp.NEUKUNDE);
Artikel artikel = new Artikel(Artikeltyp.STANDARD);
RabattService service = new RabattService();
// Act
int rabatt = service.berechneRabatt(kunde, artikel);
// Assert
assertEquals(0, rabatt, "Neukunde soll keinen Rabatt erhalten");
}
Vorteile und Nachteile
Vorteile
- Schnelles Feedback (ms)
- Hohe Fehlerlokalisierung
- Sicheres Refactoring
- Geringe Wartungskosten bei guter Struktur
Nachteile
- Initialer Aufwand für Testdoubles
- Gefahr von Over‑Engineering bei zu vielen Hilfsbibliotheken
Typische Prüfungsfragen (mit Kurzantwort)
- Was bedeutet AAA? Arrange (Vorbereiten), Act (Ausführen), Assert (Prüfen).
- Unterschied Stub vs. Mock? Stub liefert feste Antworten; Mock prüft, ob Interaktionen stattfanden.
- Warum Isolation wichtig? Verhindert, dass externe Systeme Tests verlangsamen oder unzuverlässig machen.
- Wie nennt man gute Tests?
methodName_condition_expectedResult.
Wichtigste Quellen
- https://martinfowler.com/articles/practical-test-pyramid.html
- https://junit.org/junit5/docs/current/user-guide/
- https://testing.googleblog.com