Communitygithub.com

Test-Driven Development

Eine Anleitung zur Test-first-Entwicklung mit vertikalen Slices und Tracer Bullets.

Was ist Test-Driven Development?

Diese Skill-Anleitung beschreibt eine disziplinierte Test-Driven Development (TDD)-Praxis, die sich auf verhaltensbezogene Integrationstests konzentriert. Der Kern liegt darin, Tests als Spezifikationen zu betrachten, die das öffentliche Verhalten des Systems über öffentliche Schnittstellen prüfen, anstatt Implementierungsdetails zu testen. Das Antipattern der horizontalen Slices wird explizit vermieden: Statt alle Tests auf einmal zu schreiben, arbeitet der Entwickler in vertikalen Slices (Tracer Bullets), bei denen ein Test geschrieben und sofort die minimale Implementierung umgesetzt wird. Der Workflow gliedert sich in Planung, Tracer Bullet, inkrementelle Schleife und Refactoring. Die Anleitung betont, dass Tests refaktorsicher sind, wenn sie nur das Verhalten und nicht die internen Strukturen prüfen. Sie unterstützt gängige Agenten-Plattformen und ist als wiederverwendbare Skill-Komponente konzipiert.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add madnpc/npc404-docs

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht Test-Driven Development?

Ausgabesprache

Standardmäßig wird mit dem Benutzer auf vereinfachtem Chinesisch kommuniziert; Teststrategien, Testbeschreibungen und Implementierungszusammenfassungen werden auf vereinfachtem Chinesisch verfasst. Wenn der Benutzer explizit eine andere Sprache angibt oder die bestehende Dokumentation eine andere Sprache vorschreibt, wird dieser gefolgt. Code, Befehle, Produktnamen und Zitate, die im Original erhalten bleiben müssen, werden nicht übersetzt.

Philosophie

Grundprinzip: Tests sollten das Verhalten über öffentliche Schnittstellen prüfen, nicht über Implementierungsdetails. Der gesamte Code kann sich ändern; die Tests sollten das nicht.

Gute Tests sind integrativ: Sie üben echte Codepfade über öffentliche APIs aus. Sie beschreiben, was das System tut, nicht wie es das tut. Ein guter Test liest sich wie eine Spezifikation – „Benutzer kann mit gültigem Warenkorb zur Kasse gehen“ sagt genau, welche Fähigkeit existiert. Diese Tests überleben Refactorings, weil sie sich nicht um die interne Struktur kümmern.

Schlechte Tests sind an die Implementierung gekoppelt. Sie mocken interne Kollaborateure, testen private Methoden oder verifizieren auf externen Wegen (z. B. direkte Datenbankabfrage statt Nutzung der Schnittstelle). Das Warnsignal: Der Test bricht beim Refactoring, obwohl sich das Verhalten nicht geändert hat. Wenn das Umbenennen einer internen Funktion Tests fehlschlagen lässt, haben diese Tests die Implementierung getestet, nicht das Verhalten.

Siehe tests.md für Beispiele und mocking.md für Mocking-Richtlinien.

Antipattern: Horizontale Slices

Schreiben Sie NICHT alle Tests zuerst und dann die gesamte Implementierung. Dies ist „horizontales Slicen“ – ROT wird als „alle Tests schreiben“ und GRÜN als „allen Code schreiben“ behandelt.

Das produziert miese Tests:

  • Tests, die in großen Mengen geschrieben werden, testen vorgestelltes Verhalten, nicht tatsächliches Verhalten
  • Sie testen am Ende die Form der Dinge (Datenstrukturen, Funktionssignaturen) statt benutzerseitigem Verhalten
  • Tests werden unempfindlich gegenüber echten Änderungen – sie bestehen, wenn das Verhalten bricht, und schlagen fehl, wenn das Verhalten in Ordnung ist
  • Sie überholen sich selbst, indem Sie sich auf eine Teststruktur festlegen, bevor Sie die Implementierung verstehen

Richtiger Ansatz: Vertikale Slices mittels Tracer Bullets. Ein Test → eine Implementierung → wiederholen. Jeder Test reagiert auf das, was Sie im vorherigen Zyklus gelernt haben. Da Sie den Code gerade geschrieben haben, wissen Sie genau, welches Verhalten wichtig ist und wie es zu überprüfen ist.

FALSCH (horizontal):
  ROT:   test1, test2, test3, test4, test5
  GRÜN:  impl1, impl2, impl3, impl4, impl5

RICHTIG (vertikal):
  ROT→GRÜN: test1→impl1
  ROT→GRÜN: test2→impl2
  ROT→GRÜN: test3→impl3
  ...

Workflow

1. Planung

Beim Erkunden der Codebasis lesen Sie CONTEXT.md (falls vorhanden), damit Testnamen und Schnittstellenvokabular zur Domänensprache des Projekts passen. Beachten Sie ADRs im betreffenden Bereich.

Bevor Sie Code schreiben:

  • Bestätigen Sie mit dem Benutzer, welche Schnittstellenänderungen nötig sind
  • Bestätigen Sie mit dem Benutzer, welche Verhaltensweisen zu testen sind (priorisieren)
  • Identifizieren Sie Möglichkeiten für tiefe Module mithilfe von Codebase-Design-Prinzipien, wenn die Schnittstellengrenzen unklar sind. Rufen Sie keine andere Skill automatisch auf, es sei denn, der Benutzer verlangt es explizit.
  • Listen Sie die zu testenden Verhaltensweisen auf (nicht Implementierungsschritte)
  • Holen Sie die Zustimmung des Benutzers zum Plan ein

Fragen Sie: „Wie soll die öffentliche Schnittstelle aussehen? Welche Verhaltensweisen sind am wichtigsten zu testen?“

Sie können nicht alles testen. Bestätigen Sie mit dem Benutzer genau, welche Verhaltensweisen am wichtigsten sind. Konzentrieren Sie die Testarbeit auf kritische Pfade und komplexe Logik, nicht auf jeden möglichen Randfall.

2. Tracer Bullet

Schreiben Sie EINEN Test, der EINE Sache über das System bestätigt:

ROT:   Test für erstes Verhalten schreiben → Test schlägt fehl
GRÜN:  Minimalen Code schreiben, um zu bestehen → Test besteht

Dies ist Ihr Tracer Bullet – beweist, dass der Pfad durchgängig funktioniert.

3. Inkrementelle Schleife

Für jedes weitere Verhalten:

ROT:   Nächsten Test schreiben → schlägt fehl
GRÜN:  Minimaler Code zum Bestehen → besteht

Regeln:

  • Nur ein Test nach dem anderen
  • Nur genug Code, um den aktuellen Test zu bestehen
  • Nicht auf zukünftige Tests vorausschauen
  • Tests auf beobachtbares Verhalten konzentrieren

4. Refactoring

Nachdem alle Tests bestanden sind, suchen Sie nach Refactoring-Kandidaten:

  • Duplizierung extrahieren
  • Module vertiefen (Komplexität hinter einfache Schnittstellen verschieben)
  • SOLID-Prinzipien anwenden, wo sie natürlich passen
  • Überlegen, was der neue Code über den bestehenden Code verrät
  • Tests nach jedem Refactoring-Schritt ausführen

Führen Sie niemals ein Refactoring durch, während Tests rot sind. Bringen Sie zuerst alles auf Grün.

Checkliste pro Zyklus

[ ] Test beschreibt Verhalten, nicht Implementierung
[ ] Test nutzt nur öffentliche Schnittstellen
[ ] Test würde ein internes Refactoring überleben
[ ] Code ist minimal für diesen Test
[ ] Keine spekulativen Features hinzugefügt

Verwandte Skills