Was ist testgetriebene Entwicklung (TDD)?
TDD, Test-Driven Development
Testgetriebene Entwicklung, kurz TDD für Test-Driven Development, ist eine Arbeitsweise in der Softwareentwicklung, bei der du zu jeder neuen Funktion zuerst einen automatisierten Test schreibst, der fehlschlägt, und erst danach den Code, der ihn bestehen lässt. Der Ablauf wiederholt sich in kurzen Zyklen, die jeweils nur wenige Minuten dauern.
Kaum ändert jemand eine Zeile, bricht an anderer Stelle etwas weg. Tests zuerst zu schreiben ist die Antwort auf die Frage, wie du das früh genug merkst.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
- Zyklus
- Rot, Grün, Refactoring
- Taktlänge
- Wenige Minuten pro Runde
- Verwechselt mit
- Nachträglich geschriebenen Unit-Tests
- Braucht
- Fachlogik, die ohne Infrastruktur aufrufbar ist
Der Zyklus aus Rot, Grün und Refactoring
Ein Durchlauf besteht aus drei Schritten, benannt nach der Farbe, die das Testwerkzeug anzeigt. Die Methode geht auf Kent Beck zurück, der sie Ende der 1990er-Jahre im Umfeld von Extreme Programming bekannt machte und Anfang der 2000er in seinem Buch „Test-Driven Development: By Example“ beschrieb.
-
Rot
Du schreibst einen Test für ein Verhalten, das es noch nicht gibt, und lässt ihn laufen. Er muss fehlschlagen, sonst prüft er etwas, das der Code ohnehin schon konnte.
-
Grün
Es entsteht genau so viel Produktivcode, dass der Test besteht, auch wenn die Lösung zunächst plump aussieht. Alle bisherigen Tests müssen dabei grün bleiben.
-
Refactoring
Du räumst auf, ziehst Duplikate zusammen und benennst um, ohne das Verhalten zu ändern. Nach jeder Änderung läuft die Testsuite erneut.
Die Schrittweite bestimmst du selbst. Bei einem vertrauten Problem darf ein Zyklus mehrere Zeilen umfassen, bei einer unklaren Anforderung schrumpft er auf einen einzigen Sonderfall, etwa auf eine leere Liste oder ein Datum am Monatsende. Wenn du länger als ein paar Minuten mit rotem Balken arbeitest, war der Schritt zu groß. Dann lohnt es sich, den letzten Stand zu verwerfen und kleiner neu anzusetzen.
Ein Beispiel in Python
Angenommen, ein Onlineshop soll ab 50 Euro Warenwert versandkostenfrei liefern, darunter kostet der Versand 4,90 Euro. Testgetrieben beginnst du nicht mit der Funktion, sondern mit zwei Tests, die mit pytest laufen. Beide schlagen zunächst fehl, weil es die Funktion noch nicht gibt.
# test_versand.py, Schritt Rot
from versand import versandkosten
def test_unter_grenze_kostet_versand():
assert versandkosten(49.99) == 4.90
def test_ab_grenze_versandkostenfrei():
assert versandkosten(50.00) == 0
# versand.py, Schritt Grün
def versandkosten(warenwert):
return 0 if warenwert >= 50 else 4.90 Interessant ist der zweite Test: Er zwingt dich, die Grenze genau festzulegen. Gilt „ab 50 Euro“ einschließlich 50,00 Euro? Diese Frage stellt sich beim Schreiben des Tests, also bevor jemand sie im Betrieb an einer Reklamation entdeckt. Im Refactoring-Schritt würdest du die Zahlen 50 und 4,90 als benannte Konstanten herausziehen, und die Tests bestätigen, dass sich am Verhalten nichts geändert hat.
Was die Reihenfolge im Alltag bringt
Der eigentliche Gewinn liegt weniger im Netz aus Tests als im Entwurfsdruck. Wer den Test zuerst schreibt, ruft die Funktion von außen auf, bevor sie existiert, und merkt sofort, wenn eine Klasse fünf Abhängigkeiten mitschleppt oder eine Signatur unhandlich ist. Code, der schwer zu testen ist, fällt so am ersten Tag auf und nicht erst im Review.
Der zweite Effekt zeigt sich beim Ändern. Eine Suite, die in Sekunden durchläuft, macht Refactoring risikoarm, weil du nach jedem Schritt weißt, ob noch alles hält. Deshalb ist die Laufzeit kein Nebenaspekt: Sobald ein Durchlauf mehrere Minuten braucht, startet ihn niemand mehr ständig, und der Zyklus fällt in sich zusammen.
Fehler, die den Nutzen wieder auffressen
Am häufigsten begegnet dir der Test, der nie rot war. Entsteht er nach dem Code oder wird er nach einem Fehlschlag sofort zurechtgebogen, ohne dass jemand ihn hat scheitern sehen, kann er dauerhaft grün bleiben, obwohl er nichts prüft. Der rote Lauf gehört deshalb zum Verfahren und ist keine Zugabe.
Ebenso verbreitet ist der Test, der die Implementierung nachzeichnet statt das Verhalten. Prüft er, dass eine bestimmte Methode eines Mocks in einer bestimmten Reihenfolge aufgerufen wurde, bricht er bei jedem harmlosen Umbau. Solche Tests verhindern genau das, wofür der Zyklus gedacht war. Halte dich lieber an das Ergebnis, das nach außen sichtbar ist.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Testgetriebene Entwicklung und was oft damit gleichgesetzt wird
Ein Unit-Test ist ein Werkzeug, testgetriebene Entwicklung eine Reihenfolge. Unit-Tests kannst du auch nachträglich schreiben, dann fehlt aber der Entwurfsdruck, weil die Struktur des Codes bereits feststeht.
BDD hebt denselben Zyklus auf die fachliche Ebene und formuliert die Beispiele in einer Sprache, die Fachabteilung und Entwicklung gemeinsam lesen können, oft im Format Gegeben, Wenn, Dann. Der technische Ablauf bleibt gleich, die Beispiele sind gröber und beschreiben Verhalten statt einzelner Funktionen.
Testautomatisierung besagt nur, dass Tests ohne Handarbeit laufen, unabhängig davon, wann sie entstanden sind. Ein Oberflächentest, der nachts über die fertige Anwendung läuft, ist automatisiert, hat mit TDD aber nichts zu tun.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Der Nutzen entsteht erst durch die Reihenfolge, nicht durch die Tests
In vielen Teams heißt testgetriebene Entwicklung in Wirklichkeit: Funktion fertigstellen, danach Tests nachziehen, damit die Abdeckung stimmt. Solche Tests bestätigen nur, was der Code ohnehin tut, samt der Fehler darin. Der eigentliche Gewinn liegt darin, dass du die Schnittstelle aus Sicht des Aufrufers festlegst, bevor dich eine halbfertige Implementierung in eine Richtung drängt.
Der zweite Stolperstein sind die Testebenen. Wer jeden Ablauf über Datenbank, Dateisystem und HTTP prüft, wartet Minuten auf jeden Durchlauf und bricht den Rhythmus ab. Damit der kurze Takt funktioniert, muss die Fachlogik ohne Infrastruktur aufrufbar sein, und in gewachsenen Systemen wird das oft erst nach einer sauberen Trennung der Zuständigkeiten möglich.
Und dann gibt es die Tests, die niemand mehr anfassen will: Sie prüfen interne Details statt Verhalten und schlagen bei jedem Umbau fehl, obwohl fachlich alles stimmt. Danach wird nur noch dort umgebaut, wo es keine Tests kostet, und der Rest bleibt liegen.
Testgetriebene Entwicklung lernen
Wie du Testfälle schneidest, Ergebnisse bewertest und eine Suite pflegst, die niemanden ausbremst, üben die Trainings zum Softwaretest an echtem Code.
Den Zyklus lernst du am schnellsten in einer Sprache, die du schon beherrschst, zum Beispiel in den Programmierkursen mit Python.
Kurse, die Testgetriebene Entwicklung behandeln
- pytest Einführungskurs – Testgetriebene Entwicklung von Python-Code
- Software Testing Grundlagen: Testfälle, Bugs, Abnahme
- Clean Code Entwicklerschulung
- JavaScript - Webanwendungen testen mit Jasmine, Jest, Karma und Puppeteer
- ISTQB® Certified Tester Foundation 4.0
Weitere Kurse aus diesem Bereich
- ISTQB Certified Tester - Testing with Generative AI
- ISTQB® Certified Tester – Advanced Level – Testmanagement
- Effektive KI Software-Tests mit LLMs
- Postman-Schulung: API-Abfragen / Testing für REST-APIs
- ISTQB® Certified Tester – Foundation Level – Agile Tester
- OWASP API Security Training: REST-API sicher testen
- ISTQB® Certified Tester – Foundation Level – Automotive Software Tester
Häufige Fragen
Muss ich wirklich jeden Test vor dem Code schreiben?
Welche Werkzeuge brauche ich für TDD?
Wie hoch sollte die Testabdeckung bei TDD sein?
Wird die Entwicklung dadurch nicht langsamer?
Funktioniert TDD auch mit Code, den eine KI schreibt?
Passt thematisch dazu
Den ersten Test kannst du nur schreiben, wenn das erwartete Verhalten feststeht, und dafür braucht es eine Anforderung, aus der sich ohne Rückfrage ein Testfall bauen lässt.
Nicht jedes Verhalten gehört in einen Unit-Test, deshalb lohnt vorab die Überlegung, auf welcher Ebene eine Prüfung überhaupt hingehört.
Deine Ansprechpartner
Du willst das Thema nicht nur nachschlagen, sondern anwenden können? Wir beraten dich persönlich und kostenlos.
Yves Hoppe
Weiterbildung & Beratung
Ordnet mit dir ein, welcher Kurs zu deinem Vorwissen passt.
Norbert Jansen
Beratung & Inhouse
Plant Inhouse-Trainings, die an euren eigenen Daten und Abläufen ansetzen.
Testgetriebene Entwicklung im Kurs statt im Lexikon
Nachschlagen bringt dich bis zum Verstehen. Anwenden lernst du an echten Aufgaben.