Zum Inhalt springen

Tests bremsen Entwicklung

Nicht Tests bremsen Entwicklung. Angst vor Änderungen bremst Entwicklung.

Der Satz klingt erstmal vernünftig:

Wir haben keine Zeit für Tests.

Er klingt nach Pragmatismus. Nach Lieferdruck. Nach Fokus auf das Wesentliche.

Oft bedeutet er aber etwas anderes:

Wir haben keine Zeit, heute Sicherheit aufzubauen.
Also bezahlen wir morgen mit manueller Prüfung, Regressionen, Angst und langsameren Änderungen.

Das ist der eigentliche Denkfehler.

Tests sind keine Zusatzarbeit nach der Entwicklung. Gute Tests sind Teil der Entwicklung, weil sie Verhalten überprüfbar machen.

Tests kosten Zeit. Fehlendes Feedback kostet Kontrolle.

Natürlich kosten Tests Zeit.

Ein Test schreibt sich nicht von allein. Er muss verstanden, gebaut, gepflegt und manchmal gelöscht werden.

Aber die relevante Frage ist nicht:

Wie viel Zeit kosten Tests?

Die bessere Frage ist:

Wie viel Zeit kostet uns fehlendes Vertrauen in Änderungen?

Denn ohne Tests verschwindet der Aufwand nicht. Er verlagert sich nur.

Dann wird später manuell geprüft.
Dann wird im Review geraten.
Dann wird in der Abnahme gesucht.
Dann findet der Kunde den Fehler.
Dann wird beim nächsten Refactoring gezittert.

Das Team spart vorne ein paar Stunden und zahlt hinten mit Unsicherheit, Kontextwechseln, Regressionen und wachsender Änderungsscheu.

Das fühlt sich am Anfang schneller an.

Bis jede Änderung eine kleine Mutprobe wird.

Tests sind kein Selbstzweck.

Ein Test ist dann wertvoll, wenn er Feedback früher, schneller oder verlässlicher macht.

Ohne automatisiertes Feedback merkt man Fehler oft erst spät:

  • im manuellen Test
  • im Review
  • in der Abnahme
  • im Sprint danach
  • in Produktion
  • beim Kunden
  • beim nächsten Umbau

Je später Feedback kommt, desto teurer wird es.

Nicht, weil der Fehler magisch größer wird. Sondern weil mehr Kontext verloren geht, mehr Menschen beteiligt sind, mehr Vertrauen beschädigt wird und mehr Folgearbeit entsteht.

Der teuerste Fehler ist nicht der Fehler. Es ist der späte Fehler.

Tests sind ein Sicherheitsnetz für Architekturarbeit

Abschnitt betitelt „Tests sind ein Sicherheitsnetz für Architekturarbeit“

Besonders sichtbar wird das bei Architekturarbeit.

Refactoring.
DTO-Leakage entfernen.
Komponenten entflechten.
State Management aufräumen.
Modulgrenzen schärfen.
Legacy-Code strangulieren.
Schnittstellen sauberer schneiden.

All das klingt vernünftig.

Bis jemand fragt:

Woher wissen wir, dass danach noch alles funktioniert?

Wenn die Antwort lautet „gar nicht“, bleibt schlechte Architektur liegen.

Dann wird nicht refactored.
Dann wird drumherum gebaut.
Dann wird die Komponente noch größer.
Dann wird der Store noch verworrener.
Dann wird das DTO noch tiefer ins Frontend gereicht.

Nicht, weil niemand das Problem sieht.

Sondern weil niemand sicher ändern kann.

Tests sind in solchen Situationen keine Dekoration. Sie sind der Unterschied zwischen:

Wir wissen, was wir ändern.

und:

Hoffentlich fällt es nicht um.

Der Satz „Tests bremsen“ ist nicht komplett falsch.

Er ist nur zu ungenau.

Schlechte Tests bremsen tatsächlich.

Tests, die CSS-Klassen prüfen.
Tests, die private Methoden festnageln.
Tests, die Framework-Zufälle absichern.
Tests, die bei jedem internen Umbau brechen.
Tests, die langsam, flaky und unverständlich sind.
Tests, die nur existieren, damit eine Coverage-Zahl hübsch aussieht.

Solche Tests helfen nicht. Sie erzeugen Misstrauen gegenüber der Testsuite.

Dann wird jeder grüne Build skeptisch betrachtet.
Jeder rote Build wird als „wahrscheinlich wieder flaky“ abgetan.
Jede Änderung braucht Testpflege ohne fachlichen Gegenwert.

Das ist keine Qualitätssicherung.

Das ist Bürokratie mit Assertions.

Der wichtige Satz ist:

Schlechte Tests sind kein Argument gegen Tests.
Sie sind ein Argument gegen schlechte Tests.

Die Alternative zu schlechten Tests ist nicht testlos. Die Alternative sind bessere Tests.

Gute Tests schützen Verhalten, nicht Implementierung

Abschnitt betitelt „Gute Tests schützen Verhalten, nicht Implementierung“

Gute Tests interessieren sich nicht dafür, wie elegant der Code intern gerade aussieht.

Sie interessieren sich dafür, welches Verhalten nach außen gelten muss.

Ein guter Test sagt:

Wenn diese fachliche Situation eintritt, muss dieses beobachtbare Ergebnis entstehen.

Ein schlechter Test sagt:

Diese private Methode muss genau mit diesen Parametern aufgerufen werden, obwohl das fachlich niemanden interessiert.

Der Unterschied ist gewaltig.

Gute Tests helfen beim Refactoring, weil sie erlauben, die interne Struktur zu verändern, ohne Verhalten zu verlieren.

Schlechte Tests verhindern Refactoring, weil sie interne Struktur mit Verhalten verwechseln.

Gute Tests dokumentieren Beispiele.
Schlechte Tests dokumentieren Zufälle.

Gute Tests reduzieren Risiko.
Schlechte Tests konservieren Angst.

Coverage ist nützlich.

Sie kann zeigen, welche Bereiche gar nicht berührt werden. Sie kann blinde Flecken sichtbar machen. Sie kann helfen, Diskussionen zu starten.

Aber Coverage ist gefährlich, wenn sie zum Ziel wird.

Wenn „80 Prozent Coverage“ das Ziel ist, optimiert das Team auf 80 Prozent Coverage.

Nicht zwingend auf Risikoabsicherung.

Dann entstehen Tests, die Code ausführen, aber nichts Relevantes prüfen. Getter werden getestet. Branches werden mechanisch berührt. Mocks bestätigen Mocks. Snapshots werden aktualisiert, ohne dass jemand versteht, ob Verhalten kaputt ist.

Coverage sagt:

Dieser Code wurde berührt.

Coverage sagt nicht:

Dieses wichtige Verhalten ist geschützt.

Das ist ein Unterschied, der in vielen Projekten teuer wird.

Coverage zeigt, wo Code berührt wurde. Nicht, ob das Richtige geschützt ist.

Die Testpyramide ist eine hilfreiche Heuristik.

Viele schnelle Tests unten. Weniger langsame, teure Tests oben.

Aber auch die Testpyramide ist kein Naturgesetz.

Praktischer ist die Frage:

Welches Risiko wollen wir absichern?

Klare Logik braucht oft schnelle Unit Tests.

Komponentenverhalten kann mit Component Tests sinnvoll geprüft werden.

Kritische Schnittstellen brauchen Integrationstests oder Contract Tests.

Ein paar zentrale User Journeys verdienen E2E-Tests.

Legacy-Code braucht manchmal zuerst Characterization Tests, damit vorhandenes Verhalten vor dem Umbau sichtbar wird.

Nicht jedes Risiko braucht denselben Testtyp.

Aber jedes kritische Risiko braucht irgendeine Form von Feedback.

Nicht jedes Risiko braucht denselben Test. Aber jedes kritische Risiko braucht Feedback.

Management braucht Tests gerade wegen Geschwindigkeit

Abschnitt betitelt „Management braucht Tests gerade wegen Geschwindigkeit“

Management will Geschwindigkeit.

Das ist legitim.

Produkte müssen geliefert werden. Budgets sind begrenzt. Planung braucht Verlässlichkeit. Kunden warten nicht geduldig, bis ein Team seine innere Architekturharmonie gefunden hat.

Aber genau deshalb sind Tests wichtig.

Tests sind kein Luxus für Entwickler, die gerne sauberen Code anschauen.

Tests sind ein Mechanismus, damit Lieferfähigkeit nicht bei jeder Änderung neu verloren geht.

Die bessere Management-Frage ist nicht:

Warum schreibt ihr Tests?

Sondern:

Welches Risiko sichern diese Tests ab?

Oder:

Welche Änderung wird dadurch sicherer?

Oder:

Welches manuelle Prüfen ersetzen sie?

Oder:

Welche Regression wäre teuer, wenn sie erst spät auffällt?

Das verschiebt die Diskussion weg von Testmenge und hin zu Risikosteuerung.

Und genau dort gehört sie hin.

Eine vernünftige Teststrategie ist unspektakulär

Abschnitt betitelt „Eine vernünftige Teststrategie ist unspektakulär“

Eine gute Teststrategie muss nicht religiös sein.

Sie muss nicht mit 100 Prozent Coverage wedeln.
Sie muss nicht alles über TDD lösen.
Sie muss nicht jeden Klick durch einen E2E-Test jagen.
Sie muss nicht jede private Funktion einfrieren.

Sie muss vor allem ehrlich sein.

Welche fachlichen Regeln sind kritisch?
Welche Integrationen sind gefährlich?
Welche Regressionen wären teuer?
Welche Bereiche werden häufig geändert?
Welche Legacy-Stellen traut sich niemand anzufassen?
Welche Tests sind langsam, flaky oder wertlos?

Daraus entsteht ein praktischer Zielzustand:

  • Risiken identifizieren
  • fachliche Beispiele sammeln
  • kritische Logik mit schnellen Tests absichern
  • gefährliche Integrationen gezielt prüfen
  • Legacy-Verhalten vor Refactoring charakterisieren
  • E2E-Tests auf wenige kritische Flows konzentrieren
  • flaky Tests reparieren oder entfernen
  • Coverage als Diagnose verwenden, nicht als Ziel

Das ist weniger spektakulär als Testdogma.

Aber deutlich nützlicher.

Tests machen Entwicklung nicht automatisch schnell. Sie machen sichere Geschwindigkeit möglich.

„Tests bremsen Entwicklung“ ist zu grob.

Besser wäre:

Schlechte Tests bremsen Entwicklung.
Gute Tests begrenzen Risiko.
Fehlende Tests verschieben Kosten in die Zukunft.

Oder noch kürzer:

Tests sind keine Bremse.
Schlechte Tests sind eine Bremse.
Keine Tests sind ein Kredit.
Und jede Angst vor Änderung ist eine Zinszahlung.