End-to-End-Testautomatisierung in SaaS
MariuszBild von Mariusz
Mariusz
Software

End-to-End-Testautomatisierung in SaaS

Warum wir Playwright wählten und wie es den Testprozess revolutionierte

Einleitung

Noch gut erinnere ich mich an die Zeiten, als Testautomatisierung in der Softwareentwicklung oft eine schier unüberwindbare Hürde darstellte. Manuelle Tests dominierten das Feld, und vor jedem Release mussten Entwicklerteams dutzende, wenn nicht hunderte Tests von Hand durchführen, um die Funktionalität der Anwendung sicherzustellen. Das war in den 2000er Jahren vielleicht noch akzeptabel, doch mit der steigenden Komplexität moderner SaaS-Anwendungen wurde dieser Prozess zunehmend ineffizient. Spätestens wenn man an die Integration verschiedener APIs und die Veränderungen in den Benutzerrollen dachte, stieß man mit manuellen Tests an seine Grenzen.

Heute möchte ich euch erzählen, wie wir bei einem Kundenprojekt die Herausforderungen des UI- und End-to-End-Tests meisterten. Warum wir auf Playwright setzten, welche Vorteile es uns gebracht hat, und warum wir überzeugt sind, dass es die Art und Weise, wie SaaS-Anwendungen getestet werden, revolutionieren kann.

Warum wir Playwright für End-to-End-Tests ausgewählt haben

Es gibt viele Tools für Testautomatisierung, und in den letzten Jahren ist ein regelrechter Boom an neuen Frameworks entstanden. Dennoch ist die Wahl eines geeigneten Frameworks alles andere als trivial – jeder hat so seine Vorlieben, und jedes Tool hat seine Stärken und Schwächen. Selenium hat beispielsweise lange Zeit das Bild dominiert, bis Cypress auf den Plan trat und mit intuitiven Features einen neuen Standard setzte.

Unsere Wahl fiel schlussendlich auf Playwright, ein relativ junges Testing-Framework von Microsoft. Aber warum? Playwright ermöglicht es uns, Tests nicht nur in verschiedenen Browsern (Chromium, Firefox, WebKit) parallel laufen zu lassen, sondern auch mit verschiedenen Viewports und sogar mobilen Endgeräten zu testen – das ist für uns als Software-Agentur, die SaaS-Lösungen entwickelt, entscheidend. Wir arbeiten mit Anwendungen, die sowohl am Desktop als auch auf mobilen Endgeräten absolut reibungslos funktionieren müssen.

Playwright bietet zudem hervorragenden TypeScript-Support mit async/await first und Auto-Wait. Auto-Wait bedeutet, dass Playwright automatisch auf Elemente wartet, bis sie bereit sind, bevor Aktionen wie Klicks ausgeführt werden. Es enthält auch eine Vielzahl von introspektiven Events, die sicherstellen, dass unnötige Timeouts – eine der Hauptursachen für instabile Tests – vermieden werden. Das macht die Tests robuster und vermeidet die klassischen „Flaky Tests“.

Ein weiterer Pluspunkt ist die Integration von Playwright in den CI/CD-Prozess. Mit Headless-Runnern können Tests während des Build-Prozesses automatisch ausgeführt werden. Dank eines globalen Setups und Teardowns lässt sich die Testinfrastruktur flexibel aufbauen und wieder abbauen. Die automatisierte Erstellung von Screenshots, Videos und Fehler-Traces vereinfacht es uns, Fehler zu erkennen und zu beheben.

Was macht Traces so charmant?

Mit den Traces und dem verbundenen Trace Viewer kann man jede Aktion und jeden Selektor zu jeder Zeit des Tests nachvollziehen, und zwar live und auch im Nachgang. Dafür hat man immer den Stand vor einer Aktion, während und danach. So sieht man, was selektiert wurde und wie beispielsweise ein Input befüllt wurde. On top kann man die Traces automatisch für fehlgeschlagene Tests erstellen lassen.

trace example

Platzhalter für ein Trace-Bild:

Läuft der Test dann irgendwo anders als auf der Entwicklermaschine (sogar headless in der CI), kann man sich den Trace downloaden und browsen. Neben der Oberfläche kann man dann auch die DevTools des Browsers nutzen und das DOM erkunden, um z.B. herauszufinden, warum ein Selektor nicht gefunden wurde.

Anbei noch das Video, welches Playwright in der Dokumentation für das Tracing erstellt hat.

Ein Kundenprojekt als Anwendungsbeispiel: Das Admin-Portal

Das Kundenprojekt, über das ich euch heute erzählen möchte, ist ein Administrationsportal, das Nutzern ermöglicht, verschiedene Entitäten wie Kunden, Produkte und Rechnungen zu verwalten. Die Benutzeroberfläche bietet Listen- und Kartenansichten, die über generische Komponenten realisiert werden. Das bringt naturgemäß einige Herausforderungen für die Automatisierung von Tests mit sich.

Doch wie schafft man es, ohne sich die Finger wund zu tippen, sehr viele Seiten und Oberflächen zu pflegen? Ohne Code zu duplizieren, Anpassungen an der Komponente (z. B. LazyLoading, Pagination) in alle Tests zu bekommen, ohne immer alles anpassen zu müssen? Wie schafft man es, Selektoren wiederzuverwenden?

Die Lösung: Data-Page Fixture

Um die verschiedenen Ansichten und Aktionen des Admin-Portals zu testen, verwenden wir eine sogenannte Data-Page Fixture. Die Data-Page Fixture stellt grundlegende Funktionen zur Verfügung, wie das Öffnen der verschiedenen Modi, das Erstellen und Löschen von Entitäten sowie das Navigieren zwischen den Listen- und Kartenansichten. Diese Fixture ist die Grundlage, um das Verhalten der Benutzeroberfläche auf einfache und wiederholbare Weise zu testen.

Ein Beispiel für die Implementierung der Data-Page Fixture sieht so aus:

Loading...

Mit dieser Fixture können wir grundlegende Aktionen wie das Erstellen und Löschen von Entitäten abstrahieren, sodass wir diese Logik in vielen Tests wiederverwenden können. Diese Modularität sorgt dafür, dass der Testcode übersichtlich bleibt und Änderungen leicht eingepflegt werden können, ohne an vielen Stellen Anpassungen vornehmen zu müssen.

Ableitung für konkrete CRUD-Tests

Um die CRUD-Funktionalität für bestimmte Entitäten zu testen, haben wir die Data-Page Fixture erweitert. Für jede Entität, beispielsweise einen Benutzer, leiten wir eine spezifische Fixture ab, die zusätzliche, auf diese Entität zugeschnittene Methoden beinhaltet. Das sieht in etwa so aus:

Loading...

Die UserDataPageFixture erweitert die generische Data-Page Fixture um die Möglichkeit, spezifische Eigenschaften von Benutzern zu konfigurieren. So wird der gesamte Prozess des Benutzeranlegens inklusive der Rollenzuweisung in einer einfachen Methode zusammengefasst.

Wenn der Testfall bei dieser Entität abweicht, kann man dann nach Belieben die Abläufe überschreiben. Werden diese dann in anderen Tests benutzt, wird der Ablauf angepasst. Die Pages sind sich immer sehr ähnlich und zu über 90% ist alles gleich, aber so haben wir die Möglichkeit, alles perfekt zu customizen.

Ein echter Testfall mit Playwright

Dank der klar strukturierten Fixtures lassen sich die Tests jetzt sehr einfach und vor allem lesbar gestalten. Ein Beispiel für einen echten Testfall sieht wie folgt aus:

Loading...

Der oben gezeigte Testfall ist sehr leicht lesbar und zeigt die gesamte CRUD-Operation für einen Benutzer. Dank der verwendeten Fixtures bleibt der Code kompakt und ist zugleich flexibel genug, um für weitere Tests wiederverwendet zu werden. Das ermöglicht uns eine saubere, nachvollziehbare und leicht erweiterbare Testbasis.

Wiederverwendbarkeit von Logindaten über Local Storage States

Ein weiteres wichtiges Feature ist die Wiederverwendbarkeit von Logindaten mittels gespeicherter Local Storage States. Dies ermöglicht es uns, die Login-Informationen zu speichern und in weiteren Tests zu nutzen, was sowohl Zeit spart als auch eine unabhängige und parallele Ausführung der Tests ermöglicht.

Ein Beispiel:

Loading...

Hier wird der Zustand nach dem Login gesichert:

Loading...

Je nach Benutzer kann man dann unterschiedliche Dateien nutzen und in der Konfiguration diesen Snapshot laden:

Loading...

Das spart einerseits Zeit und ermöglicht es andererseits, die Tests lose, ungekoppelt und parallel auszuführen.

Playwright als Bindeglied im CI/CD-Prozess

Eine der großen Stärken von Playwright ist die Einbindung in die CI/CD-Pipeline. Tests sollten nicht nur lokal ausgeführt werden, sondern ihre erfolgreiche Ausführung muss für das gesamte Team transparent und nachvollziehbar sein – und genau das wird durch die Einbindung in die CI/CD-Pipeline gewährleistet. So gibt es kein „Works on My Machine“-Problem mehr.

Bei jedem Build werden die End-to-End-Tests automatisch ausgeführt, und der Erfolg oder Misserfolg wird dokumentiert. Wir haben dabei JUnit Reports für die einfache Visualisierung in CI-Tools und detaillierte HTML-Berichte mit Screenshots für die Nachvollziehbarkeit der Testergebnisse.

Die Playwright-Konfiguration zur Bereitstellung im CI-Prozess sieht wie folgt aus:

Loading...

Die automatisierten Reports sind ein großer Vorteil, da so jeder Stakeholder – von Entwicklern bis hin zu Produktmanagern – sofort einen Überblick über den aktuellen Zustand der Anwendung erhält. Mit den HTML-Berichten lassen sich Fehler schnell nachvollziehen, und durch die erstellten Traces kann man im Detail verfolgen, was zu einem Problem geführt hat. Insbesondere bei der Arbeit mit mehreren Rollen und Berechtigungen ist das von unschätzbarem Wert.

Playwright als Brücke zwischen den Tests und der Realität

Die Idee hinter End-to-End-Tests mit Playwright war es, die Lücke zu schließen, die durch die übliche Testaufteilung in Unittests, Integrationstests und manuelle Tests entstand. Für dieses Kundenprojekt bedeutet das: Wir wollten sicherstellen, dass alle Systeme miteinander harmonieren – von der Authentifizierung bis zur Datenanzeige – und dass das Zusammenspiel der verschiedenen Microservices (Auth, Daten, Rechnungsstellung) wirklich in der Praxis funktioniert.

Dabei ist Playwright so konfiguriert, dass alle Systeme komplett initialisiert werden: vom Authentifizierungsservice, den Web-APIs bis hin zu den 3rd-Party-Playgrounds. Es handelt sich also nicht um simulierte Daten, sondern um ein echtes End-to-End-Testing-Szenario. So wird geprüft, ob die Tokens systemübergreifend funktionieren und ob die Daten wie gewünscht angezeigt werden. Das ist essentiell, um sicherzustellen, dass unsere Anwendung in einer realistischen Umgebung robust funktioniert.

Ein weiterer Vorteil, den wir aus den End-to-End-Tests ziehen, ist die Möglichkeit, die Anwendung in verschiedenen Browsern, Viewports und Geräten zu testen. Dies ist entscheidend in einer Welt, in der unsere Kunden ihre Anwendungen auf den unterschiedlichsten Endgeräten nutzen möchten. Playwright ermöglicht uns, sowohl mobile Browser als auch verschiedene Desktop-Auflösungen gezielt zu prüfen.

Fazit: Playwright als Gamechanger für den Testprozess

End-to-End-Tests sind für moderne Softwareentwicklung unverzichtbar geworden – und Playwright hat sich in unserem Kundenprojekt als Gamechanger erwiesen. Reine UI-Tests sind nicht ausreichend, um die Qualität einer Anwendung sicherzustellen. Die größte Herausforderung bei UI-Tests ist es, die richtige Balance zwischen Testumfang und Wartbarkeit zu finden. Hier hilft Playwright mit seiner Flexibilität und den verschiedenen Automatisierungswerkzeugen, den Testaufwand sinnvoll zu verteilen.

Dank Playwright konnten wir die Anzahl manueller Tests signifikant reduzieren und die Release-Geschwindigkeit erhöhen, ohne dabei die Qualität zu gefährden. Es ist das Bindeglied, das alle Testarten miteinander vereint und es ermöglicht, die Anwendung so zu testen, wie sie tatsächlich vom Kunden genutzt wird. Für uns war das ein enormer Gewinn – und ich kann jedem, der End-to-End-Tests für eine komplexe Anwendung in Betracht zieht, Playwright nur wärmstens empfehlen.

Ich hoffe, dass euch dieser Einblick in unseren Testprozess inspiriert hat. Falls ihr Fragen habt oder mehr über unsere Arbeit mit Playwright erfahren möchtet, meldet euch gerne – ich freue mich auf den Austausch!


Mariusz, der Gründer von Handmade Systems
NATO
TaxiKomm24
Swiss Life
SweepBusiness

Zünden Sie den Turbo für Ihr Softwareprojekt! 🚀

Nehmen Sie eine Abkürzung und finden Sie in einem 30 Minuten Call heraus, wie Ihnen unsere Experten helfen können, Ihre Softwareentwicklung zu beschleunigen: