Testpyramide
Dieser Beitrag ist eine Begriffserklärung zur Testpyramide – inklusive Prüfungsfragen und Tags.
In a Nutshell
Die Testpyramide priorisiert viele schnelle und stabile Unit Tests, weniger Integrationstests und wenige End‑to‑End‑Tests, um mit minimalen Kosten maximale Sicherheit zu erreichen. Ziel sind kurze Rückmeldungen in der CI und verlässliche Abdeckung ohne fragiles Übergewicht an UI‑Tests.
Kompakte Fachbeschreibung
Die Testpyramide strukturiert automatisierte Qualitätssicherung in Ebenen nach Kosten, Ausführungszeit und Fehlersuchpräzision.
- Unit‑Ebene: schnell, isoliert, deterministisch; hohe Fehlerlokalisierung; Nutzung von Mocks und Stubs.
- Integrationsebene: echte Komponenteninteraktion (Datenbank, Dateisystem, Netzwerk); oft mit Contract Tests zwischen Diensten.
- E2E‑Ebene: wenige, aber geschäftskritische Nutzerflüsse über UI & Infrastruktur; hohes Vertrauen, höhere Kosten.
Gute Metriken: Code Coverage (als Trend), Mutation Testing (Wirksamkeit), Flaky Rate (Stabilität). Anti‑Muster: Eiscreme‑Kegel (zu viele UI‑Tests), Sanduhr (zu wenige Unit Tests).
Prüfungsrelevante Stichpunkte
- Zielverteilung: ca. 70 % Unit, 20 % Integration, 10 % E2E (kontextabhängig): Die Pyramide verteilt Tests nach Kosten und Geschwindigkeit. Je näher am Code, desto mehr Tests sollten laufen. Diese Zahlen sind Richtwerte und können je nach Projekt variieren.
- Unit‑Ebene: schnell, isoliert, deterministisch, hohe Fehlerlokalisierung: Unit Tests prüfen einzelne Bausteine ohne externe Abhängigkeiten. Sie sind die Basis der Pyramide und liefern das schnellste Feedback.
- Integration: echte Schnittstellen, Testdatenmanagement, Container‑Services: Integrationstests prüfen das Zusammenspiel mehrerer Komponenten. Datenbanken, APIs oder Message Broker werden in der Regel real oder in Controllern simuliert.
- E2E: wenige kritische Flows, reale Umgebung nahe Produktion: End-to-End-Tests simulieren komplette Nutzerpfade. Sie sind teuer und langsam, sollten daher auf geschäftskritische Abläufe konzentriert werden.
- Contract Tests für Service‑Grenzen (Microservices): Contract Tests prüfen, ob die Schnittstelle zwischen Konsument und Anbieter eingehalten wird. Sie sind besonders wichtig in verteilten Systemen mit vielen Services.
- CI‑Pipeline: schnelle Feedbackstufen, parallele Ausführung, Artefaktversionierung: Die Pipeline sollte Unit Tests zuerst und schnell ausführen, bevor teurere E2E-Tests starten. Parallele Ausführung und klare Stufen halten die Feedbackzeit kurz.
- Metriken: Coverage, Mutation Score, Build‑Zeit, Flaky Rate: Metriken helfen, die Qualität der Tests zu bewerten. Coverage allein ist nicht aussagekräftig, der Mutation Score zeigt, ob Tests wirklich Fehler erkennen.
- Dokumentation: Teststrategie, Testfallkatalog, Risikomatrix: Eine klare Teststrategie dokumentiert, welche Tests auf welcher Ebene existieren und warum. Risikomatrizen priorisieren die Bereiche mit der höchsten Fehlerwahrscheinlichkeit.
Kernkomponenten
- Testebenen (Unit, Integration, E2E) – Die drei Ebenen der Pyramide unterscheiden sich nach Isolation, Geschwindigkeit und Kosten. Unit Tests sind klein und schnell, E2E Tests breit und realitätsnah. Jede Ebene hat einen eigenen Zweck.
- Testdoubles (Mock, Stub, Fake, Spy) – Testdoubles ersetzen echte Abhängigkeiten in Unit Tests. Mocks prüfen Interaktionen, Stubs liefern feste Werte, Fakes enthalten einfache Logik, Spies protokollieren Aufrufe.
- Testdatenstrategie (Factories, Fixtures, Seed‑Daten, Reset) – Konsistente Testdaten sind entscheidend für stabile Tests. Factories erzeugen flexible Daten, Fixtures liefern bekannte Ausgangszustände, ein Reset nach jedem Test verhindert Seiteneffekte.
- Infrastruktur im Test (Datenbank‑Container, Message‑Broker, Sandbox) – Integrationstests nutzen oft Container oder Testinstanzen für Datenbanken und Broker. Das macht Tests realistisch, aber langsamer und aufwändiger in der Wartung.
- Contract Testing (konsumentengetrieben, Versionierung) – Contract Tests prüfen Schnittstellenverträge zwischen Services. Der Konsument definiert Erwartungen, der Anbieter stellt sicher, dass sie erfüllt werden, auch bei Versionierung.
- Testausführung (CI‑Stages, schnelles Gate auf Unit‑Ebene) – Die CI-Pipeline führt Unit Tests zuerst als schnelles Qualitätsgate aus. Erst wenn diese bestehen, laufen Integrationstests und zuletzt E2E-Tests.
- Stabilität (Eliminierung von Flaky Tests, Zeit/Zufall kontrollieren) – Flaky Tests liefern unzuverlässige Ergebnisse. Durch kontrollierte Zeit, deterministische Zufallswerte und saubere Isolation lassen sie sich reduzieren oder eliminieren.
- Abdeckung & Wirksamkeit (Coverage, Mutation Testing, Risikoabdeckung) – Coverage zeigt, welche Codezeilen ausgeführt werden. Mutation Testing prüft, ob die Tests echte Fehler erkennen. Beide zusammen geben ein besseres Bild der Testqualität.
- Selektives E2E (kritische Pfade, Smoke Suite, visuelle Regression sparsam) – Nicht jeder Pfad braucht einen E2E-Test. Kritische Geschäftsprozesse, Smoke-Tests nach Deployments und gezielte visuelle Regression decken das Wesentliche ab.
- Wartung (Refactoring, gemeinsame Hilfsbibliotheken, Namenskonventionen) – Testcode ist gleich wichtig wie Produktivcode. Regelmäßiges Refactoring, geteilte Helpers und klare Namenskonventionen halten die Testbasis wartbar.
Praxisbeispiel (Bestellservice)
Unit‑Ebene:
- Arrange: Product mit Preis, DiscountPolicy Mock liefert 10 % Rabatt
- Act: OrderService.totalForBasket()
- Assert: erwarteter Betrag = berechneter Betrag (keine DB‑Zugriffe)
Integration‑Ebene:
- Arrange: reale DB im Container, Repository speichert/liest Order
- Act: OrderRepository.save() + OrderRepository.findById()
- Assert: gespeicherte Felder identisch, Transaktion rollt zurück
E2E‑Ebene:
- Arrange: Anwendung mit Browserautomatisierung starten
- Act: Nutzer legt Artikel in Warenkorb, geht zur Kasse, klickt "Bestellung abschließen"
- Assert: Bestellbestätigung sichtbar, DB‑Eintrag vorhanden, Event im Message Broker
Vorteile und Nachteile
Vorteile
- Kurze Feedbackzeiten
- Hohe Fehlerlokalisierung
- Robuste Pipeline
- Geringere Wartungskosten
- Bessere Planbarkeit
- Höhere Releasefrequenz
Nachteile
- Initialer Infrastrukturaufbau
- Pflege von Testdoubles & Fixtures
- Potenziell blinde Flecken bei falscher Verteilung
- E2E bleibt fragiler
Typische Prüfungsfragen (mit Kurzantwort)
- Warum ist die Testpyramide wirtschaftlich sinnvoll? Viele günstige Unit Tests fangen die meisten Defekte früh ab; teure E2E Tests werden auf kritische Flows begrenzt.
- Woran erkennt man zu viele UI Tests? Lange Builds, hohe Flaky Rate, häufige false negatives, schwierige Fehlerlokalisierung (Eiscreme‑Kegel).
- Wozu Contract Tests bei Microservices? Stabilisieren Schnittstellenbeziehungen, prüfen Kompatibilität unabhängig vom Gesamtsystem.
- Wie verhindert man Flaky Tests? Zeit/Zufall kontrollieren, externe Abhängigkeiten mocken/kapseln, saubere Isolation, deterministische Daten.
- Rolle von Mutation Testing? Prüft, ob Tests logisch wirksam sind (nicht nur Zeilen berühren) → bessere Aussage als reine Coverage.
Lernstrategie
- Verständniseinstieg: Vergleiche die drei Testebenen anhand eines konkreten Features (z.B. Warenkorb). Überlege, welche Logik in Unit, welche Schnittstelle in Integration und welcher Nutzerpfad in E2E getestet wird.
- Vertiefungsmethode: Schreibe zu einem bestehenden Code eine Kombination aus Unit- und Integrationstest. Beobachte Unterschiede in Geschwindigkeit, Fehlermeldung und Setup-Aufwand.
- Prüfungsfokustraining: Ordne Szenarien der richtigen Ebene zu und erkläre, warum eine falsche Verteilung (z.B. Eiscreme-Kegel) problematisch ist.
- Fehlervermeidung: Vermeide Flaky Tests von Anfang an: kontrolliere Zeit, Zufall und externe Abhängigkeiten; isoliere Tests vollständig.
Übungsbeispiel 1: Unit Test für eine Rabattberechnung
Ein Warenkorb enthält Produkte mit Preisen. Eine DiscountPolicy berechnet 10 % Rabatt. Im Unit Test wird die Policy isoliert geprüft: bei einem Eingabepreis von 100 € muss der Rabatt 10 € betragen. Externe Services oder Datenbanken werden nicht benötigt.
Übungsbeispiel 2: Integrationstest für ein Repository
Ein OrderRepository speichert und liest Bestellungen aus einer echten Datenbank im Container. Der Test prüft, ob gespeicherte Felder wiederhergestellt werden und ob Transaktionen korrekt zurückrollen. Das ist langsamer als ein Unit Test, aber realistischer.
Übungsbeispiel 3: Mutation Testing verstehen
Ein Test hat 100 % Coverage, aber ein Mutation Testing Tool ändert eine Bedingung im Code und der Test schlägt nicht fehl. Das zeigt, dass der Test die Logik nicht wirklich prüft. Mutation Testing deckt solche Lücken auf.
Übungsaufgabe 1: Testebene bestimmen
Du möchtest prüfen, ob die Berechnung des Steuerbetrags für einen Artikel korrekt ist. Auf welcher Ebene gehört der Test?
Lösung: Auf Unit-Ebene, da die Steuerberechnung eine isolierte Logik ohne externe Abhängigkeiten ist.
Übungsaufgabe 2: Verteilung beurteilen
Ein Projekt hat 500 E2E-Tests, aber nur 50 Unit Tests. Die Builds dauern lange und schlagen oft unzuverlässig aus. Welches Problem liegt vor?
Lösung: Das Projekt bildet einen Eiscreme-Kegel: zu viele UI-Tests, zu wenige Unit Tests. Die Lösung ist eine stärkere Verteilung hin zu Unit Tests und selektive E2E-Tests.
Übungsaufgabe 3: Flaky Test analysieren
Ein Test schlägt manchmal fehl, weil er auf eine aktuelle Uhrzeit zugreift. Wie lässt sich das beheben?
Lösung: Die Uhrzeit muss im Test kontrolliert werden, zum Beispiel durch einen Testdouble für die Zeitquelle oder durch feste Werte. Das macht den Test deterministisch.
Themenanalyse
- Technischer Kern: Testebenen und deren Zusammenspiel. Die Pyramide definiert klar, welche Tests auf welcher Ebene laufen. Unit Tests sichern die Logik, Integrationstests das Zusammenspiel, E2E-Tests kritische Nutzerpfade.
- Implementierungsherausforderungen: Balance zwischen Geschwindigkeit und Realitätsnähe. Zu viele E2E-Tests verlangsamen die Pipeline, zu wenige Integrationstests übersehen Schnittstellenfehler. Die richtige Verteilung ist projektspezifisch.
- Sicherheitsimplikationen: Mutation Testing und Coverage für kritische Pfade. Besonders bei sicherheitsrelevantem Code reicht Coverage nicht aus. Mutation Testing prüft, ob Tests fehlerhafte Varianten tatsächlich erkennen.
- Dokumentationspflichten: Teststrategie und Testkatalog als Projektdokumentation. Eine dokumentierte Teststrategie erklärt, welche Tests auf welcher Ebene existieren und welche Risiken damit abgedeckt werden.
- Wirtschaftliche Bewertung: Testaufwand vs. Fehlerkosten und Releasegeschwindigkeit. Gute Tests reduzieren teure Produktionsfehler und ermöglichen schnellere Releases. Schlechte Tests kosten durch Wartung und Flakiness.
Wichtigste Quellen
- https://martinfowler.com/articles/practical-test-pyramid.html
- https://testing.googleblog.com
- https://pact.io