TDD: Was es ist, Testprinzipien und Methodik

Autor: IT Sectr Veröffentlicht: 2026-04-09 Lesezeit: 9 Min.

Test-Driven Development (TDD) ist eine Entwicklungsmethodik, bei der Tests vor der Code-Implementierung geschrieben werden. Der Entwickler formuliert zunächst das erwartete Verhalten als fehlschlagenden Test, schreibt dann den minimalen Code, um ihn zu bestehen, und refaktoriert anschließend das Ergebnis. Laut Martin Fowler (2023) ist TDD keine Testtechnik – es ist eine Entwurfstechnik, die die Architektur diszipliniert und die Anzahl der Fehler in der Code-Schreibphase reduziert.

Wichtige Punkte

  • TDD ist eine Methodik, bei der der Test vor der Implementierung geschrieben wird, nicht danach
  • Der Red-Green-Refactor-Zyklus ist die Grundlage von TDD: roter Test, grüner Test, Refactoring
  • JUnit und Mockito sind die wichtigsten Werkzeuge für TDD in der Android-Entwicklung
  • Die Codeabdeckung in TDD-Projekten übersteigt dank der „Test-First“-Disziplin oft 90%
  • Refactoring ohne Angst, Funktionalität zu brechen – ein Hauptvorteil des TDD-Ansatzes

Was ist TDD?

Test-Driven Development ist eine Softwareentwicklungspraxis, bei der automatisierte Tests das Schreiben von Produktionscode bestimmen. Im Gegensatz zum traditionellen Ansatz, bei dem Code geschrieben und dann getestet wird, kehrt TDD die Reihenfolge um: Zuerst wird der Test geschrieben, dann der Code, der den Test besteht.

Als Begründer von TDD gilt Kent Beck, der diese Praxis Ende der 1990er Jahre im Rahmen der Extreme-Programming-Methodik (XP) formulierte. In seinem Buch „Test-Driven Development: By Example“ (2002) beschrieb Beck fünf Regeln von TDD, die kanonisch wurden: Schreibe den Test vor dem Produktionscode, schreibe genau so viel Code, wie zum Bestehen des Tests nötig ist, und refaktoriere nach jedem Zyklus.

Schlüsselprinzipien von TDD

Das erste Prinzip – der Test definiert die Schnittstelle. Der Entwickler ist gezwungen, darüber nachzudenken, wie die Komponente verwendet wird, bevor er darüber nachdenkt, wie sie implementiert wird. Dies bildet von Anfang an eine saubere API.

TDD als Entwurfstechnik

Das zweite Prinzip – minimale Implementierung. Wenn der Test geschrieben ist, schreibt der Entwickler genau so viel Produktionscode, wie zum Bestehen benötigt wird – keine Zeile mehr. Dies verhindert vorzeitige Abstraktion und übermäßige Komplexität, die Martin Fowler als Speculative Generality bezeichnet.

Unterschied zwischen TDD und herkömmlichem Testen

Der Hauptunterschied zwischen TDD und nachträglichem Testen ist die Disziplin der Reihenfolge. Bei TDD überprüft der Test nicht nur den Code – er lenkt seine Struktur. Laut einer Microsoft-Research-Studie (Nagappan et al., 2008) zeigen Teams, die TDD anwenden, eine Reduzierung der Fehlerdichte um 40–90% im Vergleich zu Teams, die den traditionellen Ansatz verwenden.

Der Red-Green-Refactor-Zyklus

Der Red-Green-Refactor-Zyklus ist eine dreistufige Sequenz, die für jeden neuen Test wiederholt wird. Red: Einen Test schreiben, der nicht bestanden wird. Green: Den minimalen Code schreiben, um den Test zu bestehen. Refactor: Den Code verbessern, ohne sein Verhalten zu ändern.

Red-Phase: Einen fehlschlagenden Test schreiben

Der Entwickler schreibt einen Test, der eine noch nicht implementierte Funktionalität überprüft. In dieser Phase muss der Test fehlschlagen – dies bestätigt, dass der Test tatsächlich etwas überprüft. In der Android-Entwicklungsumgebung zeigt das JUnit-5-Framework für fehlgeschlagene Tests eine rote Anzeige, was der Phase ihren Namen gab.

kotlin
class CalculatorTest {
    fun testAddition() {
        val result = Calculator().add(2, 3)
        Assertions.assertEquals(5, result)
    }
}

Green-Phase: Minimale Implementierung

In dieser Phase wird der minimale Produktionscode geschrieben, der ausreicht, um den Test zu bestehen. Keine Redundanz – nur das, was für die grüne Anzeige nötig ist. Wenn die Implementierung eine Konstante sein kann, sei sie eine Konstante. Das Refactoring erfolgt im nächsten Schritt, wenn neue Tests erscheinen.

kotlin
class Calculator {
    fun add(a: Int, b: Int): Int {
        return a + b
    }
}

Refactor-Phase: Verbesserung ohne Risiko

Der grüne Test ist eine Versicherung für das Refactoring. Der Entwickler kann die Implementierung umschreiben, die Leistung optimieren oder die Lesbarkeit verbessern, in dem Vertrauen, dass der Test sofort jede Abweichung vom erwarteten Verhalten erkennt. In der Android-Entwicklung ist diese Phase besonders wichtig, um gemeinsame Schnittstellen zu extrahieren und Code-Duplizierung zu reduzieren.

Vorteile von TDD in der mobilen Entwicklung

Die Anwendung von TDD in mobilen Projekten bietet messbare Vorteile, die sowohl durch akademische Forschung als auch durch die Praxis führender Entwicklungsstudios bestätigt werden.

Reduzierte Fehlerdichte

Eine IBM-Studie (Bhat & Nagappan, 2006) an vier Industrieprojekten zeigte, dass Teams, die TDD verwenden, 40% weniger Fehler produzieren im Vergleich zu ähnlichen Teams, die nach dem traditionellen Schema arbeiten. Für die mobile Entwicklung, wo die Kosten für die Behebung eines Fehlers nach der Veröffentlichung im Google Play deutlich höher sind als in der Code-Schreibphase, ist diese Metrik entscheidend.

Code-Dokumentation durch Tests

Mit TDD geschriebene Tests dienen als lebendige Dokumentation der API. Ein Entwickler, der zum Projekt stößt, kann die Tests lesen und verstehen, wie jede Komponente verwendet werden soll. Dies ist besonders wertvoll bei hoher Teamfluktuation – einer typischen Herausforderung mobiler Studios.

Sicheres Refactoring

Eine Codeabdeckung von über 90% ermöglicht es Entwicklern, Refactoring ohne Angst vor dem Brechen von etwas durchzuführen. Google bezeichnet in seinem Buch „Software Engineering at Google“ (2020) die Testabdeckung als Schlüsselfaktor, um die Codebasis in Projekten mit Millionen von Codezeilen sauber zu halten.

Werkzeuge und Frameworks für TDD

Das TDD-Ökosystem in der mobilen Entwicklung umfasst Werkzeuge für Unit-Tests, Mocking und UI-Komponentenprüfung – sowohl für Android als auch für iOS.

WerkzeugPlattformZweck
JUnit 5Android (Kotlin/Java)Basis-Framework für Unit-Tests
MockitoAndroidErstellung von Mock-Objekten und Aufrufverifikation
MockKAndroid (Kotlin)Mocking mit Kotlin-First-Syntax und Coroutine-Unterstützung
TurbineAndroidTesten von Kotlin Flow und reaktiven Streams
XCTestiOS (Swift)Standard-Testframework

Framework-Wahl für Android

Für Android-Projekte mit Kotlin umfasst der Standard-Stack JUnit 5 + MockK. MockK ist Mockito vorzuziehen, da es Kotlin-First-Funktionen – sealed classes, Coroutinen und suspend-Funktionen – ohne zusätzliche Konfiguration unterstützt.

Werkzeuge für iOS

In der iOS-Entwicklung wird TDD über XCTest implementiert – das integrierte Apple-Framework, das Assertions, Testklassen und CI/CD-Integration über Xcode Server oder GitHub Actions bietet. Für Mocking unter iOS werden die Bibliotheken Cuckoo und OHHTTPStubs verwendet.

Codebeispiele mit TDD in Kotlin

Betrachten wir ein reales TDD-Szenario in Kotlin für Android – das Testen eines Benutzer-Repositories. Zuerst schreiben wir den Test, dann die Implementierung, die den Test besteht.

Schritt 1: Test für UserRepository

kotlin
class UserRepositoryTest {
    private val api = mockk<UserApi>()
    private val dao = mockk<UserDao>()
    private val repo = UserRepository(api, dao)

    fun `when api returns user then cache and emit`() = runTest {
        val user = User(1, "Alice")
        coEvery { api.getUser(1) } returns user
        every { dao.insert(user) } returns Unit

        val result = repo.getUser(1)

        assertEquals(user, result)
        verify { dao.insert(user) }
    }
}

Schritt 2: Minimale Implementierung

kotlin
class UserRepository(
    private val api: UserApi,
    private val dao: UserDao
) {
    suspend fun getUser(id: Int): User {
        val user = api.getUser(id)
        dao.insert(user)
        return user
    }
}

Schritt 3: Test für Caching mit Offline-Modus

Nach dem Bestehen des ersten Tests fügen wir einen zweiten hinzu – wir überprüfen das Verhalten bei einem Netzwerkfehler. Nun bestimmt der Test, dass das Repository bei API-Fehler Daten aus dem Cache zurückgeben soll.

kotlin
fun `when api fails then return cached user`() = runTest {
    val cached = User(1, "Cached Alice")
    coEvery { api.getUser(1) } throws IOException()
    every { dao.getById(1) } returns cached

    val result = repo.getUser(1)

    assertEquals(cached, result)
}

Häufige Fehler bei der Einführung von TDD

Der Übergang zu TDD ist mit typischen Fehlern verbunden, die alle Vorteile der Methodik zunichtemachen können. Das Verständnis dieser Fallstricke hilft Teams, die Praxis effektiver einzuführen.

Zu große Tests

Das erste und häufigste Anti-Pattern ist das Testen eines zu großen Funktionsumfangs in einem einzigen Test. Ein Test sollte genau eine Behauptung überprüfen. Wenn ein Test fehlschlägt, sollte der Entwickler ohne zusätzliches Debugging genau wissen, was kaputt ist.

Ignorieren der roten Phase

Der zweite Fehler ist das Schreiben eines Tests, der von Anfang an bestanden wird. Wenn der Test nicht mindestens einmal rot war, gibt es keine Gewissheit, dass er tatsächlich etwas überprüft. Regel: Vertraue niemals einem Test, den du nicht fehlschlagen gesehen hast.

Auslassen des Refactorings

Der dritte häufige Fehler ist das Anhalten in der grünen Phase. Refactoring ist kein optionaler, sondern ein obligatorischer Schritt im Zyklus. Ohne ihn degradiert die Codebasis, Tests werden spröde und die Vorteile von TDD gehen verloren.

  • Testen der Implementierung statt des Verhaltens – Tests werden an Details gebunden und brechen bei jedem Refactoring
  • Fehlende Tests für Grenzfälle – leere Listen, Null-Werte, Randbedingungen bleiben ungedeckt
  • Ignorieren der Testgeschwindigkeit – langsame Tests verlangsamen die Rückkopplungsschleife und töten die TDD-Disziplin

Häufig gestellte Fragen

Ist TDD eine Test- oder eine Entwurfstechnik?

TDD ist in erster Linie eine Entwurfstechnik, keine Testtechnik. Tests in TDD spielen die Rolle einer Spezifikation: Sie definieren die API der Komponente vor ihrer Implementierung. Kent Beck selbst nennt TDD „eine Disziplin des Entwurfs, nicht des Testens“.

Wie lange dauert es, TDD zu meistern?

Laut Studien von Microsoft Research benötigen Teams 3 bis 6 Monate kontinuierlicher Praxis, damit TDD zur Gewohnheit wird. In den ersten 2–3 Wochen sinkt die Produktivität um 15–30%, kehrt aber nach der Anpassung auf das ursprüngliche Niveau zurück oder übertrifft es aufgrund der reduzierten Debugging-Zeit.

Ist TDD für UI-Komponenten geeignet?

Ja, aber mit Einschränkungen. Für UI-Logik (ViewModel, State) ist TDD direkt anwendbar. Für visuelle Komponenten (Compose UI, SwiftUI Views) ergänzt Snapshot-Testing TDD, ersetzt es aber nicht. Es wird empfohlen, Geschäftslogik und Darstellung zu trennen.

Kann TDD in Legacy-Projekten angewendet werden?

Für Legacy-Code wird die Strategie der „Charakterisierungstests“ empfohlen – bei denen Tests auf das bestehende Verhalten geschrieben und dann der Code refaktoriert wird. Dieser Ansatz wird in Michael Feathers’ Buch „Working Effectively with Legacy Code“ (2004) beschrieben und ermöglicht die schrittweise Einführung von TDD.

Wie kombiniert sich TDD mit Clean Architecture?

TDD und Clean Architecture verstärken sich gegenseitig. Saubere Architektur erfordert klare Grenzen zwischen Schichten, und TDD zwingt den Entwickler, diese Grenzen durch Tests zu entwerfen. Die Domänenschicht wird isoliert mit Mock-Abhängigkeiten getestet, die Datenschicht durch Integrationstests.

Zusammenfassung

  • TDD – Methodik, bei der der Test vor der Implementierung geschrieben wird, was eine saubere API formt und die Architektur lenkt
  • Der Red-Green-Refactor-Zyklus – die grundlegende Einheit von TDD: fehlschlagender Test → minimale Implementierung → Refactoring
  • Die Anwendung von TDD reduziert die Fehlerdichte laut IBM- und Microsoft-Research-Studien um 40–90%
  • Hauptwerkzeuge für die Android-Entwicklung: JUnit 5, MockK, Turbine für Flow
  • MockK ist Mockito in Kotlin-Projekten aufgrund der Unterstützung von Coroutinen und sealed classes vorzuziehen
  • Häufige Fehler: zu große Tests, Auslassen der roten Phase, Ignorieren des Refactorings
  • Empfohlene Einführungsstrategie – schrittweise, beginnend mit der Domänenschicht und neuen Features, ohne zu versuchen, den gesamten Legacy-Code auf einmal abzudecken

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch