Begriff
Unit Test
Warum wichtig?
Dieser Begriff ist ein Knoten im SengakujiWorks-Wissensnetz. Nutze Level 0 für die erste Einordnung, Level 1 für Praxis, Level 2 für technische Struktur und Level 3 für Grenzen, Fallstricke und Expertenkontext.
Du baust ein Auto. Bevor du das Auto fährst, prüfst du jede Einzelteile: "Funktioniert die Zündkerze? Ja." "Funktioniert der Blinker? Ja." Das ist ein Unit Test. Du testest die kleinste mögliche Einheit (Funktion/Klasse) isoliert vom Rest. Ohne Datenbank. Ohne Netzwerk. Nur Code. Wenn der Unit Test fehlschlägt, weißt du genau: "Die Zündkerze ist kaputt" (und nicht der Motor an sich). Sie sind extrem schnell (Millisekunden). Tausende laufen in Sekunden.
Merksatz: Ein automatisierter Softwaretest, der eine einzelne Komponente (Funktion, Klasse) isoliert auf ihre korrekte Funktionalität überprüft.
Jest (JS) Beispiel:
// Function
function add(a, b) { return a + b; }
// Test
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3);
});
Wenn jemand a - b schreibt, wird der Test rot.
1. Mocking & Stubbing
Die Kunst der Isolation.
Deine Funktion getUser() ruft die Datenbank.
Das darf im Unit Test nicht passieren (zu langsam, DB könnte down sein).
Du "mockst" die DB.
"Tu so, als ob die DB da wäre. Wenn ich dich rufe, gib einfach {name: 'Max'} zurück."
Tools: Mockito (Java), jest.mock.
Ein Test, der das Netzwerk berührt, ist kein Unit Test (sondern Integration Test).
2. TDD (Test Driven Development)
Die Hardcore-Schule. Du schreibst den Test bevor du den Code schreibst.
- Schreibe Test "addiere(1,1) soll 2 sein".
- Führe aus -> Rot (Funktion fehlt).
- Schreibe Funktion (minimal).
- Führe aus -> Grün.
- Refactor. Das erzwingt testbaren, modularen Code.
3. Assertions & Matcher
Gute Tests haben präzise Fehlermeldungen.
Schlecht: assertTrue(result == expected). (Fehler: "False is not True").
Gut: assertEquals(expected, result). (Fehler: "Erwartet 5, aber bekam 3").
Nutze Matcher: assertThat(list).contains("Apfel"). Das ist lesbarer.
1. Zyklomatische Komplexität
Was macht eine Funktion schwer zu testen? Die Anzahl der Verzweigungen (if, for, while, case).
Die Zyklomatische Komplexität ist eine Zahl, die sagt: "Wie viele Pfade gibt es durch diesen Code?".
Eine Funktion mit Komplexität 10 braucht mindestens 10 Unit Tests, um alle Pfade einmal abzudecken. Wenn ein Unit Test zu kompliziert wird ("Ich brauche 100 Zeilen Setup für 2 Zeilen Test"), ist das ein Warnsignal: Die Funktion macht zu viel (Single Responsibility Principle verletzt) und sollte aufgeteilt werden.
2. Dependency Inversion für Testbarkeit
Wie testet man Code, der fest mit dem Dateisystem oder einer API verdrahtet ist?
Gar nicht – man muss ihn umbauen.
Statt new FileSystem() direkt in der Klasse aufzurufen, übergibt man das Dateisystem als Parameter im Konstruktor (Dependency Injection).
Im echten Betrieb übergibt man das echte Filesystem. Im Unit Test übergibt man einen "Mock", der nur im RAM lebt. Code, der so geschrieben ist, dass er leicht "gemockt" werden kann, ist oft qualitativ hochwertiger, da er weniger "harte Kopplungen" (tight coupling) hat.
3. Snapshot Testing
Besonders beliebt im Frontend (React/Vue).
Statt jedes Detail einzeln zu prüfen (expect(title).toBe("Hallo")), macht man einen "Snapshot" vom Ergebnis.
Der Test speichert das komplette HTML-Gerüst in einer Textdatei. Beim nächsten Durchlauf vergleicht Jest das neue Ergebnis mit dem Snapshot.
Vorteil: Man merkt sofort, wenn sich das Layout unabsichtlich geändert hat.
Gefahr: Man drückt zu oft "U" (Update Snapshot), ohne die Änderungen wirklich zu prüfen, was den Test wertlos macht.
Quick-Check
FIRST Prinzip?
Fast, Isolated, Repeatable, Self-validating, Timely. Die 5 Regeln für gute Unit Tests. Wenn ein Test flakig ist (manchmal grün, manchmal rot), ist er Müll.Private Methoden testen?
Streitthema. Die reine Lehre sagt: Nein. Teste nur das öffentliche Interface (Public API). Private Methoden sind Implementierungsdetails. Teste sie indirekt über die Public Aufrufe. Sonst wird Refactoring zur Hölle.Setup/Teardown?
beforeEach()undafterEach(). Um den Zustand (Variablen) vor jedem Test sauber zurückzusetzen. Verhindert "Leaking States", wo Test A den Test B beeinflusst (Seiteneffekte).