Die Testpyramide zuschneiden: wie viele Tests auf welche Ebene gehören
Die Verteilung ergibt sich aus Laufzeit und Zuordenbarkeit, nicht aus einer Prozentangabe aus einem Buch. Was ihr messt, entscheidet, wo ihr landet.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Die Form kippt, und niemand merkt es rechtzeitig
Fast jede Suite beginnt richtig herum und kippt dann langsam. Der Grund ist unspektakulär: Ein Oberflächentest ist die naheliegendste Übersetzung eines manuellen Testfalls. Wer bisher geklickt hat, schreibt auf, was er geklickt hat. So entstehen über zwei Jahre dreihundert Ende-zu-Ende-Tests, eine Handvoll Integrationstests und eine Unit-Ebene, die nur die Bibliotheksfunktionen abdeckt.
Sichtbar wird das erst an zwei Stellen. Die Laufzeit wächst auf eine halbe Stunde, sodass niemand die Suite mehr lokal startet und die Rückmeldung ausschließlich aus der Pipeline kommt. Und ein rotes Ergebnis sagt nicht mehr, wo der Fehler liegt, weil an einem Ende-zu-Ende-Weg zehn Komponenten beteiligt sind. Beides zusammen macht aus der Suite ein Warnsystem, das zwar meldet, aber nicht lokalisiert.
Der dritte Effekt ist der teuerste: Wenn die Zuordnung fehlt, wird jede Ursachensuche zur Detektivarbeit. Ein Team, das für jeden roten Lauf eine halbe Stunde braucht, um überhaupt festzustellen, welche Schicht schuld ist, hört irgendwann auf, genau hinzusehen. Von da an ist die Verteilung der Testebenen kein Stilthema mehr, sondern der Grund, warum niemand mehr auf die Tests hört.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Der Ablauf, Schritt für Schritt
Sechs Stationen, von der Bestandsaufnahme bis zur regelmäßigen Nachmessung. Die Reihenfolge ist nicht beliebig: Wer verschiebt, bevor er das Risiko kennt, räumt an der falschen Stelle auf.
- 1
Die vorhandene Suite vermessen
Zähl die Tests je Ebene, miss die Laufzeit je Ebene und erheb die Fehlschlagquote je Test über die letzten Wochen. Wenn eure Suite keine klare Trennung nach Ebenen kennt, ist das schon der erste Befund. Ein grober Zuschnitt reicht für den Anfang: Läuft ein Test ohne Systemstart, mit gestartetem Dienst oder mit Browser und vollständiger Umgebung?
Geschafft, wenn: Eine Tabelle mit drei Zeilen, aus der hervorgeht, wo die Zeit und wo die Instabilität sitzt.
- 2
Das Risiko kartieren, bevor ihr verschiebt
Schreib mit dem Fachbereich auf, welche Fehler wirklich wehtun: Geldbeträge, Berechtigungen, Fristen, Datenverlust, rechtliche Pflichten. Diese Liste bestimmt, welche Prüfungen unter keinen Umständen wegfallen dürfen. Sie ist auch die einzige belastbare Antwort auf die Frage, wie viel Abdeckung genug ist, denn ohne sie diskutiert ihr über Prozentzahlen statt über Folgen.
Geschafft, wenn: Eine priorisierte Liste von Fachbereichen mit der jeweiligen Folge eines unentdeckten Fehlers.
- 3
Die Ebenen für euer System definieren
Legt schriftlich fest, was bei euch ein Unit-Test, ein Integrationstest und ein Ende-zu-Ende-Test ist, und zwar entlang eurer eigenen Grenzen. Martin Fowler weist zu Recht darauf hin, dass die mittlere Ebene den unklarsten Namen hat und deshalb am häufigsten ausgelassen wird. Nehmt ein Kriterium, das jeder prüfen kann, etwa ob ein Test ohne Netz und ohne laufende Datenbank durchläuft.
Geschafft, wenn: Eine halbe Seite Definition, an der sich in jedem Review entscheiden lässt, wo ein neuer Test hingehört.
- 4
Von oben nach unten verschieben
Nimm die teuersten und instabilsten Oberflächentests und frag bei jedem, welche Aussage er eigentlich trifft. Meistens sind es mehrere, und die meisten davon lassen sich eine oder zwei Ebenen tiefer prüfen. Übrig bleibt ein schmaler Rest, der wirklich das Zusammenspiel prüft. Diesen Rest behaltet ihr, alles andere ersetzt ihr, statt es zu löschen.
Geschafft, wenn: Weniger Ende-zu-Ende-Tests bei gleicher fachlicher Abdeckung und deutlich kürzerer Laufzeit.
- 5
Den Lauf in zwei Stufen aufteilen
Trenn den schnellen Lauf, der bei jeder Änderung startet, vom langsamen Lauf vor der Auslieferung. Der schnelle Lauf enthält alles, was ohne vollständige Umgebung auskommt, und muss unter der vereinbarten Zeitgrenze bleiben. Der langsame Lauf enthält die Ende-zu-Ende-Wege und die Prüfungen gegen echte Fremdsysteme. Nur der schnelle Lauf blockiert das Zusammenführen von Änderungen.
Geschafft, wenn: Rückmeldung in Minuten bei jeder Änderung, vollständige Absicherung vor jeder Auslieferung.
- 6
Die Form regelmäßig nachmessen
Setzt einen festen Termin, etwa einmal im Quartal, an dem ihr die Tabelle aus Schritt eins erneut erhebt und mit der letzten vergleicht. Wichtiger als die absoluten Zahlen ist die Richtung: Wächst die oberste Ebene schneller als die unterste, kippt die Form gerade wieder. Ohne diesen Termin passiert die Nachmessung nie, weil sie nie dringend ist.
Geschafft, wenn: Eine Zeitreihe, an der ihr Abweichungen erkennt, bevor die Laufzeit sie erzwingt.
Fünf Messpunkte, und die Form wird sichtbar
- 01 Wie lange dauert der Lauf, der bei jeder Änderung startet? Über zehn Minuten ist zu lang.
- 02 Wie viele Stellen kommen als Ursache infrage, wenn ein Test rot wird? Je weniger, desto besser.
- 03 Wie hoch ist die Fehlschlagquote je Ebene? Instabilität sammelt sich fast immer ganz oben.
- 04 Welche Ebene hat den letzten echten Fehler zuerst gemeldet? Ebenen ohne Treffer prüfen das Falsche.
- 05 Wie oft wird dieselbe Fachregel auf mehreren Ebenen geprüft? Jede Doppelung kostet dauerhaft.
Woran ihr die Verteilung festmacht
Sechs Kriterien, die sich alle messen lassen. Sie ersetzen die Prozentdiskussion durch Zahlen, die in eurem eigenen Projekt entstehen.
Die Rückmeldezeit als harte Grenze setzen
Der Lauf, der bei jeder Änderung startet, sollte in unter zehn Minuten ein Ergebnis liefern. Das ist die Größenordnung, ab der Entwicklung noch im Zusammenhang der eigenen Änderung ist. Diese Grenze bestimmt die Form der Pyramide stärker als jede Prozentvorgabe, weil sie langsame Tests automatisch nach oben und nach hinten drängt.
Zuordenbarkeit als zweites Kriterium
Frag bei jedem Test, wie viele Stellen als Ursache infrage kommen, wenn er rot wird. Bei einem Unit-Test ist es eine Funktion, bei einem Schnittstellentest eine Komponente, bei einem Ende-zu-Ende-Test der halbe Systemaufbau. Je enger die Antwort, desto mehr Wert hat das rote Ergebnis, und desto weiter unten gehört der Test hin.
Die tiefstmögliche Ebene je Aussage suchen
Für jede Prüfung gilt die gleiche Frage: Lässt sich diese Aussage eine Ebene tiefer treffen? Eine Berechnung gehört in einen Unit-Test, ein Statuscode und eine Nutzlast in einen Schnittstellentest, und der Weg über die Oberfläche prüft nur, ob die Teile miteinander verbunden sind. Diese Regel erklärt den größten Teil der Form.
Doppelungen zwischen den Ebenen aufspüren
Wenn dieselbe Fachregel unten in drei Unit-Tests und oben noch einmal in vier Oberflächentests geprüft wird, zahlt ihr viermal für dieselbe Aussage. Solche Doppelungen entstehen unbemerkt, weil sie in unterschiedlichen Dateien und oft von unterschiedlichen Leuten geschrieben werden. Eine Durchsicht je Fachbereich findet sie zuverlässig.
Nach Ebene messen, wo Fehler gefunden werden
Führt über einige Monate mit, welche Ebene welchen Fehler zuerst gemeldet hat. Wenn eine Ebene selten oder nie als erste anschlägt, prüft sie entweder das Falsche oder das bereits woanders Geprüfte. Diese Zahl ist unbequemer als eine Abdeckungsquote und deutlich aussagekräftiger.
Zwei Läufe statt eines
Ein schneller Lauf bei jeder Änderung mit Unit- und Schnittstellentests, ein langsamerer Lauf mit den wenigen Ende-zu-Ende-Wegen vor der Auslieferung oder nachts. Ohne diese Trennung müsst ihr euch zwischen langsamer Rückmeldung und gestutzter Abdeckung entscheiden, und beide Antworten sind schlecht.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Woher die Pyramide kommt und was sie tatsächlich behauptet
Die Darstellung stammt von Mike Cohn und erschien in seinem Buch Succeeding with Agile. Seine ursprünglichen Ebenen hießen Unit Tests, Service Tests und User Interface Tests. Die Aussage war von Anfang an keine Quotenvorgabe, sondern eine Kostenaussage: viele kleine und schnelle Tests unten, einige gröbere in der Mitte, sehr wenige, die das ganze System von außen bedienen.
Google hat für die eigene Arbeit lange eine Orientierung von etwa siebzig Prozent Unit-Tests, zwanzig Prozent Integrationstests und zehn Prozent Ende-zu-Ende-Tests veröffentlicht, zusammen mit einer ausführlichen Begründung, warum zu viele Ende-zu-Ende-Tests langsam sind, häufig instabil werden und im Fehlerfall schwer zuzuordnen sind. Diese Zahlen sind kein Naturgesetz, und für eine Anwendung mit viel Logik im Browser oder für eine reine Datenverarbeitung sehen sie anders aus.
Die Begründung dahinter hält aber jeder Prüfung stand, und sie ist reine Kombinatorik. Ein Ende-zu-Ende-Test bindet Oberfläche, Anwendungslogik, Datenbank, Netz und meist noch ein Fremdsystem ein. Wenn jede dieser Schichten in neunundneunzig von hundert Läufen mitspielt, dann fällt der Gesamttest trotzdem in etwa fünf von hundert Läufen aus einem Grund aus, der mit eurem Code nichts zu tun hat.
Warum die mittlere Ebene der Streitpunkt ist
Martin Fowler benennt in seinem Artikel zur Pyramide genau die Stelle, an der die meisten Teams straucheln: Der Begriff Service Test ist schwer zu greifen, und in der Folge lassen viele Entwicklungsteams diese Ebene schlicht aus. Was übrig bleibt, ist eine Suite mit sehr kleinen und sehr großen Tests und nichts dazwischen, und genau in dieser Lücke sitzen die Fehler, die im Zusammenspiel zweier Komponenten entstehen.
Die Auflösung ist unspektakulär: Definiert die Ebenen an euren eigenen Grenzen, nicht an Lehrbuchbegriffen. Ein brauchbares Kriterium ist die Frage, welche Infrastruktur ein Test braucht. Kein Netz und keine Datenbank ist unten. Eigene Anwendung samt Datenbank, aber ohne Browser und ohne Fremdsysteme, ist die Mitte. Alles zusammen mit echter Oberfläche ist oben. Diese drei Sätze reichen, und sie sind in jedem Review überprüfbar.
Der Nebeneffekt einer klaren Definition ist, dass die mittlere Ebene endlich Kandidaten bekommt. Prüfungen gegen die eigene Schnittstelle, gegen ein Datenbankschema, gegen die Serialisierung eines Nachrichtenformats, gegen die Migrationsskripte: All das ist zu groß für einen Unit-Test und zu klein für einen Ende-zu-Ende-Test, und all das ist wertvoll.
Die Gegenthese und wann sie recht hat
Kent C. Dodds hat der Pyramide die Testing Trophy entgegengestellt, mit einer breiteren Mitte und einer zusätzlichen Grundschicht aus statischer Prüfung, also Typprüfung und Linting. Sein Argument: Mit den heutigen Werkzeugen ist ein Integrationstest im Frontend nicht mehr teuer, und er liefert deutlich mehr Zuversicht als ein Unit-Test für eine einzelne Komponente, die niemand isoliert benutzt.
Für Oberflächen mit viel Zustand im Browser trifft das zu. Wenn eine Komponente nur im Zusammenspiel mit ihrem Zustandsspeicher und ihrem Router überhaupt Sinn ergibt, dann prüft ein isolierter Test vor allem die eigene Nachbildung dieser Umgebung. Auch Fowler weist darauf hin, dass sich Oberflächen mit heutigen Rahmenwerken durchaus auf Unit-Ebene prüfen lassen und die Oberfläche deshalb nicht automatisch ganz oben stehen muss.
Für ein Backend mit Fachlogik gilt die Gegenthese nicht. Eine Preisberechnung mit vierzehn Sonderfällen gehört in vierzehn schnelle Tests direkt an der Funktion und nicht in einen Integrationstest, der jedes Mal eine Datenbank braucht. Die praktische Konsequenz lautet deshalb nicht Pyramide oder Testing Trophy, sondern: Die Form folgt daraus, wo in eurem System die Komplexität sitzt.
Was ihr messt und was ihr besser nicht als Ziel setzt
Vier Zahlen tragen: die Laufzeit des schnellen Laufs, die Fehlschlagquote je Ebene, die Zahl der Testfälle je Ebene und die Frage, welche Ebene den letzten echten Fehler zuerst gemeldet hat. Zusammen ergeben sie ein Bild, das ehrlich ist, weil keine dieser Zahlen sich leicht schönen lässt.
Die Codeabdeckung gehört ausdrücklich nicht in diese Liste, jedenfalls nicht als Zielgröße. Sie sagt, welche Zeilen ausgeführt wurden, nicht welches Verhalten geprüft wurde. Sobald eine Abdeckungsvorgabe zur Kennzahl wird, entstehen Tests, die Code durchlaufen und kaum etwas zusichern. Als Suchwerkzeug bleibt die Abdeckung dagegen nützlich: Ein Blick auf die nicht abgedeckten Stellen zeigt schnell, ob dort etwas Wichtiges liegt.
Die zweite Zahl mit Nebenwirkung ist die absolute Zahl der Testfälle. Mehr Tests sind nicht besser, sie sind erst einmal nur mehr Pflege. Eine Suite, die nach einer Durchsicht dreißig Prozent kleiner ist und dieselben Aussagen trifft, ist eine Verbesserung und sieht in jeder Statistik nach einem Rückschritt aus. Wer diese Zahl berichtet, sollte sie mit der Laufzeit und der Fehlschlagquote zusammen zeigen.
Eine bestehende Suite umbauen, ohne alles anzuhalten
Ein Neubau kommt nicht infrage, denn während der Umbauzeit müsste die Entwicklung weiterlaufen, und niemand bekommt dafür Budget. Der Weg, der funktioniert, ist schrittweise und an die normale Arbeit gekoppelt: Jeder neu gefundene Fehler wird auf der tiefstmöglichen Ebene abgesichert, bevor er behoben wird. Nach einem Jahr wächst die Basis dadurch von selbst, und zwar genau dort, wo es tatsächlich Fehler gibt.
Der zweite Hebel ist die Regel für neue Tests. Ab einem festgelegten Datum entsteht kein neuer Oberflächentest mehr, ohne dass jemand im Review begründet, warum die Aussage nicht eine Ebene tiefer möglich ist. Das ist kein Verbot, sondern eine Begründungspflicht, und sie reicht, um das langsame Kippen aufzuhalten.
Der dritte Hebel ist die Durchsicht der teuersten Bestandstests. Sortier die Ende-zu-Ende-Tests nach Laufzeit und nach Fehlschlagquote und nimm dir jeden Monat die obersten drei vor. Innerhalb eines Jahres ist so der Großteil der schlimmsten Fälle abgearbeitet, und das ohne ein Projekt, das jemand genehmigen muss.
Dazu passende Kurse
Wer die Verfahren kennt, mit denen aus einer Anforderung Fälle entstehen, füllt die Ebenen begründet statt nach Gefühl, und dafür gibt es Kurse zum systematischen Testentwurf .
Die unterste Ebene entsteht dort, wo Code geschrieben wird, deshalb sind Python-Kurse mit Schwerpunkt auf Testcode für viele Teams der ehrlichere Einstieg.
Wie sicher bist du beim Thema wirklich?
Lesen fühlt sich schnell nach Können an. Ein kurzer Test zeigt dir, was davon schon sitzt und wo sich ein Kurs lohnt. Kostenlos, ohne Anmeldung, mit einer Erklärung zu jeder Antwort.
Wo du genau das übst
Sehr umfangreicher Überblick über Zusammenhänge und Anwendungsbereiche. Sehr zu empfehlen.
Effektives, gemeinsames Erarbeiten der Aufgaben mit vielen praktischen Tipps.
Sehr guter Trainer und gute Aufbereitung der Inhalte und auch eingehen auf Fragen der Beteiligten.
Häufige Fragen
Gilt die Verteilung siebzig zu zwanzig zu zehn für uns?
Was zählt bei uns überhaupt als Unit-Test?
Wie viele Ende-zu-Ende-Tests sind zu viele?
Brauchen wir eine Vorgabe für die Codeabdeckung?
Wo gehören Vertragstests zwischen Diensten hin?
Deine Ansprechpartner
Du bist dir nicht sicher, welcher Kurs oder welches Level zu dir passt? Wir beraten dich persönlich und kostenlos.
Yves Hoppe
Weiterbildung & Beratung
Hilft dir, aus dem Programmierung-Programm den passenden Kurs für deinen Stand zu finden.
Norbert Jansen
Beratung & Inhouse
Plant mit dir Inhouse-Trainings, die auf eure Abläufe und euren Datenbestand zugeschnitten sind.
Die Ebenen an eurer eigenen Anwendung durchziehen
Wenn der Testentwurf noch wackelt, ist ein Grundlagenkurs zu Testfällen, Fehlermeldungen und Abnahme der schnellere Weg. Wenn die Basis der Pyramide fehlt, hilft ein Kurs zu testgetriebener Entwicklung mit pytest, weil dort genau die unterste Ebene entsteht. Beide gibt es bei cmt offen und inhouse.