Blog

Testpyramide in der Praxis

Aktualisiert Oktober 21, 2025
11 Minuten

 

Heutzutage wollen wir neue Software schneller und häufiger bereitstellen, in der Regel mit Prozessen wie Continuous Integration oder Delivery. Eine schnellere Entwicklung hat zwar ihre Vorteile, aber ein häufiger Engpass bei diesen Ansätzen ist der Bedarf an automatisierten UI-Tests. Wir haben eine enorme Anzahl davon und müssen daher bis zu einigen Stunden auf Testergebnisse warten. Selbst dann finden wir oft viele falsch-negative Ergebnisse, so dass wir noch mehr Zeit aufwenden, um zu analysieren und zu bestätigen, dass der Fehler beim Test und nicht bei der Anwendung lag.
In diesem Artikel möchte ich Sie anleiten und erklären, wie wir diesen Ansatz der Testpyramide auf eine Beispielanwendung anwenden können

Was ist die Testpyramide?

Die Grundidee einer Testpyramide besteht darin, ein ausgewogenes Verhältnis von automatisierten Tests auf verschiedenen Ebenen zu erreichen. Tests, die auf der Ebene der Benutzeroberfläche geschrieben werden, sind am anfälligsten und langsam. Aus diesem Grund sollten wir nur wenige davon haben.

Die Idee der Testpyramide besteht darin, so viele Tests wie möglich in niedrigere Schichten zu verschieben. Wenn wir einige Validierungen oder Berechnungen auf der Backend-Seite (BE) durchführen, sollten wir diese Tests in die Serviceschicht verschieben. Ebenso sollten wir natürlich für den ordnungsgemäßen Zustand und die Wartung der Software eine solide Basis von Unit-Tests haben, die sehr schnell und einfach zu schreiben/zu warten sind.

Warum scheitern Tester oft an der Umsetzung der Pyramide?

Wenn es um Testteams und die gesamte Branche geht, haben wir alle schon einmal von Testpyramiden gehört und stimmen dem Konzept zu, weil es uns einfach richtig erscheint.

Und doch haben wir sehr oft Probleme, sie umzusetzen.

Wie kommt das?

Anstelle einer Pyramide haben wir oft etwas, das mit Testsilos oder einer Eistüte verglichen werden kann. Wir testen alles und überall. Folglich haben wir Tonnen von Unit-, Integrations- und UI-Tests.

Und warum? Denn die meisten Tester haben ihre Erfahrungen mit automatisierten Tests auf der UI-Schicht gemacht. Wir haben gesehen, wie die Tests ausgeführt wurden und dass man sich wie ein normaler Benutzer durch die Anwendung 'klickt'. Wir haben gesehen, dass solche Tests bei der Suche nach Regressionsfehlern gut sind und wir vertrauen ihnen.

Andererseits hatten viele von uns nicht viel Erfahrung mit Tests auf niedrigeren Schichten und selbst wenn, dann war es keine gute Erfahrung oder die Ergebnisse solcher Tests waren für uns Tester nicht sichtbar. Mit der Idee einer Testpyramide sollten wir uns von dem lösen, was uns ein Gefühl der Sicherheit für Tests auf niedrigeren Schichten gibt. Und am Anfang ist das schwer!

In diesem Artikel möchte ich Sie anleiten und erklären, wie wir diesen Ansatz der Testpyramide auf eine Beispielanwendung anwenden können. Werfen wir einen Blick darauf, wie es aussieht und funktioniert.

Beispiel einer Testpyramide

Bevor wir beginnen, sollten wir uns die Dummy-Anwendung ansehen, die der Star dieses Beispiels sein wird:

Die Anwendung besteht aus 2 Seiten: einer Liste von Benutzern und einer Seite "Neuen Benutzer hinzufügen".

Vom Backend aus gesehen haben wir nur 2 Endpunkte: einen für die Erstellung eines neuen Benutzers und einen für den Abruf der Liste der Benutzer.

Ein typischer Ansatz für eine solche Anwendung wäre das Schreiben automatisierter Tests auf der UI-Ebene mit Tools wie Selenium WebDriver, um Szenarien für die Erstellung neuer Benutzer und die Überprüfung der Benutzerliste abzudecken. Solche Tests würden alle positiven und negativen Szenarien abdecken. Die Entwickler würden einige grundlegende Unit-Tests schreiben, die den UsersService überprüfen, der für die Geschäftslogik verantwortlich ist.

Ist ein solcher Ansatz falsch? Nun, bei einer so kleinen Anwendung macht es keinen großen Unterschied, wo wir sie automatisieren, da wir für die Ausführung all dieser Tests nur 5 Minuten benötigen. Aber wenn unsere Anwendung wächst, werden wir in Zukunft viel mehr Tests haben. Das ist ein echtes Geschäftsproblem, mit dem sich viele auseinandersetzen müssen - und jetzt ist der perfekte Zeitpunkt, um zu planen, wie wir dieses Problem angehen wollen.

Stellen wir uns also eine Situation vor, in der wir etwas an unserem Backend-Service ändern und es schnell veröffentlichen möchten. Wie bereits erwähnt, müssten wir alle automatisierten Tests durchführen, um sicherzugehen, dass wir nichts kaputt gemacht haben. Die nächste Frage lautet: "Sollten wir sie alle ausführen?"

Wäre es ausreichend, wenn wir nur Unit-Tests durchführen? Wir alle wissen, dass die Antwort nein lautet. Unsere Änderungen sind möglicherweise nicht rückwärtskompatibel und wir könnten die gesamte Anwendung zerstören, wenn unsere Unit-Tests gleichzeitig grün sind. Aus diesem Grund müssen wir unsere End-to-End-Tests (e2e) auf der UI-Ebene durchführen. Diese sind jedoch anfällig und langsam und außerdem schwer zu schreiben und zu pflegen. Lassen Sie uns überlegen, wie wir unsere Tests so planen können, dass sie schnell und häufig veröffentlicht werden können - sowohl für das Frontend (FE) als auch für das Backend (BE) der App.

Und wie sieht das in der Praxis aus?

Testen der Pyramid Foundation

Ein typisches Testpyramidenmodell sieht vor, mehr Tests auf die API-Ebene zu verlagern. Richtig - das ist gut für unsere BE, aber was ist mit unserer FE-App? Können wir sie auch schneller freigeben und einige andere Tests durchführen, die uns über mögliche Probleme informieren?

Die Antwort auf all diese Fragen und Bedenken finden Sie in der folgenden Testpyramide, die in 2 Hälften unterteilt ist: eine für BE und eine für FE.

 

Pyramide für Backend testen

Werfen wir zunächst einen Blick auf die rechte Seite der Pyramide - diese umfasst die Tests, die zur Freigabe unserer BE-Anwendung ausgeführt werden müssen.

Schritt 1. Einheitstests

Diese sollten unsere Dienste sowie die darin enthaltene Geschäftslogik testen und darüber hinaus sollten diese Tests klein und unabhängig sein. Zum Glück sind wir uns alle einig, dass wir sie brauchen. Sie sind einfach zu schreiben und zu pflegen und außerdem schnell auszuführen.

Schritt 2. Komponententests

Die nächste Ebene der Pyramide für BE-Dienste ist die Ebene der Komponententests. Hier möchten wir überprüfen, ob unsere Endpunkte funktionieren und sich korrekt verhalten. Die BE-Komponententests werden uns zusammen mit den Unit-Tests darüber informieren, ob unser BE-Service wie erwartet funktioniert, und zwar mit allen Informationen, die wir benötigen. An diesem Punkt ist es verlockend zu sagen, dass wir auf der Grundlage dieser Tests unseren BE-Service guten Gewissens freigeben können. Doch was kann noch passieren? Wir könnten unsere App immer noch kaputt machen, wenn sie live geht - und was könnte der Grund dafür sein?

Entweder haben wir eine rückwärtskompatible Änderung vorgenommen oder wir haben die Adresse unseres Dienstes geändert. Aber sollten BE-Komponententests nicht rückwärtskompatible Änderungen abfangen? Nun, in der Theorie - ja - aber das Team, das an der jeweiligen Änderung gearbeitet hat (der Teil, der rückwärtsinkompatibel sein könnte), hat vielleicht nicht daran gedacht. Sie haben die Tests durchgeführt, von denen einige fehlgeschlagen sind, aber da sie diese Änderung eingeführt haben, haben sie auch die Tests aktualisiert, um sie zu berücksichtigen. Das ist der Grund, warum es nicht ausreicht, nur Unit- und Komponententests durchzuführen. Um dieses Problem zu lösen, können wir die nächste Pyramidenstufe einführen - Integrationstests.

Schritt 3. Integrationstests

Kehren wir zu unserem Problem zurück - das Team hat eine inkompatible Änderung eingeführt und die Unit-Tests haben bestanden, während die Komponententests fehlgeschlagen sind, aber das Team hat beschlossen, sie zu korrigieren (da die Änderung beabsichtigt war), so dass alle Tests bisher grün sind. Was uns hier helfen kann, sind verbrauchergesteuerte Vertragstests. Diese werden vom Verbraucher unseres BE-Dienstes geschrieben - das kann z.B. unser FE-Team sein.

Solche Tests definieren, wie der Verbraucher unsere BE verwenden wird und welche Erwartungen er hat. Hier testen wir nicht die Geschäftslogik der Endpunkte, da dies auf Komponentenebene geschieht. Stattdessen konzentrieren wir uns nur darauf, wie unser Verbraucher diese Endpunkte nutzen wird.

In unserer Beispielanwendung können wir Tests definieren, die erwarten, dass wir bei einem Aufruf des Endpunkts GET "api/users" eine Liste von Benutzern erhalten, wobei jedes Benutzerobjekt die folgenden Informationen enthält: id, name und surname. Wir können den Typ des erwarteten Wertes und natürlich den erwarteten Antwortstatuscode definieren. Pact (ein Beispiel-Framework für verbrauchergesteuerte Vertragstests) bietet einen Pact-Broker, einen Server, auf dem wir alle "Pacts" speichern können. Das sind Dateien, die Informationen darüber enthalten, was unsere Verbraucher von unserem BE-Service erwarten. Wenn wir also alle erforderlichen Tests durchführen wollen, können wir sie einfach herunterladen und gegen unseren BE-Service laufen lassen. In Fällen, in denen etwas fehlschlägt, kann das Team die Tests nicht einfach korrigieren, da sie vom Team für Verbraucheranwendungen geschrieben wurden. Wir sind also gezwungen, unsere Änderungen rückwärtskompatibel zu machen oder mit dem Team der Verbraucheranwendung über geplante Änderungen zu kommunizieren und zu vereinbaren, wie wir sie angehen.

Zu diesem Zeitpunkt haben wir Unit-Tests, Komponententests und Integrationstests durchgeführt. Wir wissen, dass unser Service wie erwartet funktioniert und unsere Änderungen abwärtskompatibel sind. Sind wir bereit für die Veröffentlichung?

Einige von uns werden vielleicht "ja!" sagen, und ich stimme zu, dass wir auf der e2e-Testebene keine Probleme im Zusammenhang mit unserem BE finden sollten, aber es besteht immer die Möglichkeit, dass wir es doch tun - vor allem, wenn wir noch lernen, wie wir eine Testpyramide in unserem Projekt verwenden.

Vielleicht sind wir auch nicht sicher, was wir auf jeder Ebene testen sollen.

Es kann z.B. passieren, dass wir die Anwendung auf den unteren Ebenen nicht mit geeigneten Tests abdecken und Fehler auf höhere Ebenen gelangen. In einer solchen Situation empfehle ich, den gefundenen Fehler zunächst mit Tests auf einer niedrigeren Ebene (Einheit/Komponente) zu reproduzieren. Dies wird uns helfen zu verstehen, welche Fehler durch automatisierte Tests auf jeder Ebene gefunden werden können. E2E-Tests sind wichtig und zielen nicht darauf ab, Fehler zu finden (da diese bereits vorher gefunden werden sollten), sondern uns die Gewissheit zu geben, dass die Anwendung als Ganzes korrekt funktioniert. Auf dieser Ebene sollten wir so wenige Tests wie möglich durchführen und die Tests, die wir noch durchführen, sollten sich auf den Benutzerfluss konzentrieren.

In unserer Beispielanwendung sehe ich nur einen E2E-Test, der geschrieben werden kann: Der Benutzer erstellt ein neues Benutzerkonto, wird zur Liste der Benutzer weitergeleitet und kann den erstellten Benutzer in der Benutzerliste sehen. Sie erwarten vielleicht Tests zur Überprüfung der Validierung auf der FE-Schicht - sie sind hier, aber auf der linken Seite der Pyramide.

Lassen Sie uns nun einen Blick auf die andere Seite der Pyramide werfen, die für die visuelle Seite unserer Anwendung verantwortlich ist.

Pyramide für Frontend testen

Schritt 1. Einheitstests

Auch hier beginnen wir mit Unit-Tests. Auf diese werde ich nicht näher eingehen, denn wir sind uns alle einig, dass wir sie brauchen.

Schritt 2. Komponententests

Viele moderne FE-Anwendungen sind auf Storybooks aufgebaut. Wir bauen unsere FE-Anwendung aus kleinen Komponenten auf, die wiederverwendbar sind. Ein Beispiel für eine solche Komponente kann eine Eingabe mit Validierung sein. Dies ist ein Ansatz, den wir beispielsweise in unseren Designsystemen verwenden. Die Komponententests für die FE-Anwendung umfassen also alle Tests, die diese kleinen Komponenten überprüfen. Solche Tests sollten bei jeder Änderung in unserem Storybook ausgeführt werden.

Schritt 3. Integrationstests

Wenn wir die FE-App von den BE-Diensten getrennt haben, können wir die nächste Stufe hinzufügen - Integrationstests. Wir können alle unsere BE-Dienste simulieren und unsere Seiten, Formulare und Vorlagen einfach testen, ohne uns um eine funktionierende BE kümmern zu müssen. Solche Tests lassen sich schneller ausführen und sind viel stabiler (da wir nicht auf Testdaten angewiesen sind). In unserer Beispielanwendung können wir alle möglichen negativen Szenarien bei der Erstellung eines Benutzerformulars testen, wir können verschiedene Kombinationen von Benutzerlisten testen (leer, viele Ergebnisse, Blättern, Sortieren usw.).

Auch hier könnten wir denken, dass wir mit FE-Einheitstests, Komponenten- und Integrationstests sicher genug sind, um die FE zu veröffentlichen. Sind wir das? Nun - nein, noch nicht. Wie bereits erwähnt, könnte unsere FE falsche Pfade zum BE haben, so dass sie vielleicht einfach nicht funktioniert. Es könnte sein, dass wir als FE-Team keine ordentlichen Vertragstests geschrieben haben und das Team, das für die BE verantwortlich ist, den Vertrag gebrochen hat, da es sich dessen nicht bewusst war. Deshalb brauchen wir wieder einige e2e-Tests, die in unserer Pipeline laufen.

Die Spitze der Pyramide

Endlich haben wir die Spitze unserer Pyramide erreicht, wir haben jede Schicht mit automatisierten Tests implementiert und wir haben auch unsere FE & BE Anwendungen mit einer ausreichenden Anzahl automatisierter Tests abgedeckt. Das Tüpfelchen auf dem i unserer Testpyramide sind explorative Tests. Diese Testtechnik hilft uns, neue Möglichkeiten zu entdecken, wie unsere Anwendung genutzt werden könnte, indem wir sie einfach manuell testen, ohne vorbereitete Testskripte oder Szenarien.

Auf diese Weise können wir Fehler so früh wie möglich erkennen und sofort beheben!

Geschäftsperspektive

Umfassende Tests sind für den Erfolg eines jeden Projekts unerlässlich, aber eine nicht ausgefeilte Strategie wird die Markteinführung nur verzögern. Eine richtig umgesetzte Testpyramide, die sowohl das Frontend als auch das Backend unterstützt - einschließlich einer Portion Automatisierung -, sorgt jedoch für schnellere Veröffentlichungszeitpläne, ohne dass die endgültige Qualität darunter leidet.

Contact

Let’s discuss how we can support your journey.