Zum Inhalt springen

Suchen...

Cypress

Cypress statt Selenium: Warum echte Browser-Tests stabiler sind, wie Component Testing die Test-Pyramide rettet und wo die Grenzen des Tools liegen.

7 Min. Lesezeit
Cover für Cypress

Cypress ist ein Testautomatisierungstool für Web-Anwendungen, das sowohl End-to-End-Tests als auch Component-Tests abdeckt. Component-Tests mounten einzelne Komponenten isoliert im echten Browser, ohne die gesamte Anwendung zu starten. Kernvorteile sind visuelles Echtzeit-Feedback während der Testausführung, DOM-Snapshots bei Fehlern und deutlich stabilere Tests gegenüber emulationsbasierten Alternativen wie Jest.

Das Wichtigste in Kürze

  • Cypress führt Komponenten-Tests im echten Browser aus, was flaky Tests durch fehlerhafte DOM-Emulation, wie sie etwa bei Jest auftreten, deutlich reduziert.
  • Das visuelle Daumenkino-Feature von Cypress zeigt für jeden Teststep einen DOM-Snapshot vor und nach der Aktion, was Debugging-Zeit massiv verkürzt.
  • Testparallelisierung, ein kostenpflichtiges Cloud-Feature von Cypress, lässt sich auch selbst implementieren, etwa über GitLab-Pipelines mit mehreren Runnern.
  • Die Cypress Testing Library ermöglicht es, Elemente über Labels und Test-IDs statt über fragile DOM-Pfade zu selektieren, was Tests stabiler und benutzerorientierter macht.

Was ist Cypress und wofür wird es genutzt?

Cypress ist ein Testautomatisierungstool für Webanwendungen. Es startete als End-to-End-Werkzeug und positionierte sich anfangs als direkter Gegenspieler zu Selenium, mit dem Versprechen, schneller und stabiler zu sein.

Der Fokus auf Web ist kein Zufall. Es entstehen immer weniger native Clients und immer mehr Webanwendungen, und Cypress ist genau für diese Welt gebaut. Ende 2020 kam ein zweiter Anwendungsbereich dazu: Component Testing.

Der entscheidende technische Unterschied zu vielen Alternativen liegt in der Ausführung. Cypress testet im echten Browser, statt eine Browserumgebung zu emulieren. Tools wie Jest emulieren das Frontend, und diese Emulation wird bei komplexen Oberflächen instabil. In der Praxis äußert sich das in extrem hohen Timeouts, weil gesuchte Elemente nicht erscheinen oder ein Button-Klick ins Leere läuft.

Warum visuelles Feedback das Debugging verändert

Cypress liefert während der Testausführung ein sichtbares Bild der Oberfläche. Du siehst direkt, was das Tool gerade tut, und nicht nur eine Textmeldung über einen nicht gefundenen DOM-Knoten.

Andere Testumgebungen im Angular-Umfeld wie Karma oder Jasmine zeigen ebenfalls die Anwendung während des Tests, sind dabei aber langsam. Cypress kombiniert die Geschwindigkeit eines Tests mit dem visuellen Feedback. Findet ein Test einen Button nicht, siehst du daneben, was Cypress auf der Oberfläche erkennt.

Dehla Sokenou hebt ein Feature besonders hervor: eine Art Daumenkino über die Teststeps. Du fährst mit der Maus über einen einzelnen Schritt und siehst einen DOM-Snapshot vorher und nachher. Gibst du Text in ein Feld ein, ist er im Vorher-Snapshot leer und im Nachher-Snapshot gefüllt. Drückst du einen Löschen-Button, ist das Element davor da und danach weg.

Cypress schafft es, die Schnelligkeit eines Tests zu verbinden mit dem visuellen Feedback. Und das macht es sehr einfach, auf Fehlersuche zu gehen.

Dehla Sokenou

Component Testing dreht die Test-Pyramide wieder richtig herum

Im Frontend werden traditionell sehr viele End-to-End-Tests geschrieben und vergleichsweise wenige Unit- oder Komponententests. Damit steht die Test-Pyramide oft auf dem Kopf. Component Testing wirkt genau diesem Effekt entgegen.

Mit Component Testing prüfst du eine einzelne Komponente losgelöst vom Rest der Anwendung. Die Anwendung muss dafür nicht laufen. Cypress nimmt den vorhandenen Code und mountet die jeweilige Komponente isoliert.

Die Isolation funktioniert über die üblichen Mittel von Component-Test-Frameworks. Du kannst Spies, Mocks oder einen Interceptor nutzen. Der Interceptor fängt etwa API-Calls ab und liefert Standardwerte zurück, sodass die Komponente wirklich als einzelnes Artefakt prüfbar wird.

Die Unterstützung war anfangs auf React und Vue beschränkt, Angular kam später dazu. Auch die Stabilität war zu Beginn ein Problem, selbst für React. Diese Kinderkrankheiten gelten inzwischen als ausgemerzt.

End-to-End und Component Testing im selben Tool

Cypress deckt beide Teststufen ab und trennt sie strukturell sauber. Der praktische Unterschied im Testcode ist gering, aber klar.

Im End-to-End-Test steuerst du mit einem visit eine URL an. Im Component Testing mountest du stattdessen die Komponente direkt. Beide Varianten beginnen mit einem describe für die Beschreibung und nutzen die typische it-Struktur, etwa “it should delete” für einen Testfall, der das Löschen eines Elements per Button-Klick prüft.

Auch die Ablage folgt dieser Trennung. Komponententests liegen als Spec-Dateien direkt neben der Komponente, im Frontend ein üblicher Standard. End-to-End-Tests liegen in einem eigenen Verzeichnis parallel zur Anwendung.

Die End-to-End-Tests in ein separates Repository auszulagern ist technisch möglich, bringt aber einen Nachteil mit sich: Ändert sich die Anwendung, vergisst du leicht, die ausgelagerten Tests anzupassen. Same Repository, andere Stelle, ist deshalb meist die bessere Wahl.

Test-Driven Development im Frontend wird greifbar

Cypress eignet sich für test-driven Development im Frontend, weil die Toolunterstützung das Schreiben von Tests vor der Implementierung erleichtert. Genau diese Unterstützung ist die Voraussetzung dafür, dass TDD im Alltag funktioniert.

Der Ablauf ist konkret. Du baust eine leere Komponente, schreibst einen Test, und siehst, dass die erwarteten Elemente fehlen. Dann ergänzt du die Elemente. Im nächsten Schritt prüfst du etwa, ob ein Input-Feld ein Pflichtfeld ist, der Test schlägt fehl, und du fügst die Eigenschaft in der Komponente hinzu.

Der Cypress Runner läuft dabei neben der IDE und startet bei jeder Änderung am Frontend den Test automatisch neu. Du musst nicht erst auf einen Play-Button drücken, sondern fährst den Runner einmal hoch und siehst laufend, wie weit du bist.

Stabiler als die Vorgänger, auch in der Pipeline

Der größte praktische Gewinn nach der Umstellung von Jest auf Cypress sind deutlich weniger flaky Tests. Flaky Tests sind die Blinker, die mal durchlaufen und mal umfallen, ohne dass sich am Code etwas geändert hat.

Bei der Migration wurden gezielt zuerst die Problemfälle angegangen: die Langläufer mit hohen Timeouts und die instabilen Tests. Das Ergebnis: Cypress läuft trotz echtem Browser schnell genug und produziert spürbar weniger Blinker. Drei regelmäßig umfallende Tests können sonst dazu führen, dass du beim Deployen zwanzig Mal auf den Knopf drückst, bis es durchläuft.

Auch die Fehlersuche in der Pipeline profitiert. Im Fehlerfall legt Cypress einen DOM-Snapshot als Screenshot ab. So wurde sichtbar, dass manche Tests fehlschlugen, weil noch Toasts über anderen Elementen lagen und diese verdeckten. Ein Bild zeigt das sofort, eine reine Textmeldung nicht.

Wie viele Tests laufen, und wie schnell?

Die Geschwindigkeit der Testausführung ist hoch, obwohl im echten Browser getestet wird. Das einmalige Hochfahren des Runners dauert etwas, die eigentliche Ausführung läuft danach sehr schnell.

Im genannten Projekt liegt das Verhältnis bei rund 500 zu 600 Tests im Vergleich zwischen verbliebenen Jest-Tests und Cypress-Tests, wobei es inzwischen mehr Cypress-Tests gibt. Diese Frontend-Tests laufen unter zehn Minuten, etwa so lange wie die Backend-Tests.

Möglich macht das die Parallelisierung. Die Frontend-Testsuite wird in kleinere Häppchen aufgeteilt, jedes Häppchen läuft auf einem eigenen Runner. Frontend- und Backend-Tests sind dadurch ungefähr gleichzeitig fertig, sodass das Paketieren auf keine Seite warten muss. Bei Bedarf lassen sich weitere Runner ergänzen.

Open Source mit kommerziellem Kern, aber selten gebraucht

Cypress ist ein Open-Source-Projekt mit einer kommerziellen Firma dahinter. Die Open-Source-Variante lässt sich praktisch ohne Einschränkungen nutzen.

Einige Funktionen bleiben der kommerziellen Variante vorbehalten, etwa die Testparallelisierung über die Cloud sowie ein Management-Dashboard und Flaky-Test-Management. Die Parallelisierung lässt sich aber selbst abbilden, im genannten Fall über eine GitLab-Pipeline, die die Testsuite aufteilt und auf mehrere Runner verteilt. Dafür braucht es die kommerzielle Cloud nicht.

Eine kleine Umfrage im Publikum bestätigte das Muster: Viele setzen Cypress ein, niemand meldete sich für die kommerzielle Variante. Für viele Teams ist die Open-Source-Version ein guter Einstieg, und die Zusatzfeatures lassen sich bei Bedarf nachbuchen oder selbst bauen.

Wo Cypress an Grenzen stößt

Cypress ist ein Werkzeug für Webanwendungen, und genau dort liegen auch die Grenzen. Hast du neben der Webanwendung native Clients, die du gemeinsam end-to-end testen willst, ist Cypress das falsche Tool.

Auch beim Multitabbing wird es eng. Eine Anwendung mit mehreren Tabs lässt sich nur mit Workarounds abdecken, und in solchen Fällen passt Cypress oft nicht. Für ein Backend in Java bleibt ohnehin ein anderes Werkzeug wie JUnit die richtige Wahl. Tools sollten passend eingesetzt werden, nicht erzwungen.

Dazu kommt das Tempo der Webentwicklung. Mit Playwright gibt es eine ernstzunehmende Alternative, und das Feld verändert sich schneller, als man alles sichten kann. Ob Cypress morgen noch das Tool der Wahl ist, lässt sich nicht garantieren.

Tipps für den Einstieg

Wer mit Cypress startet, sollte zwei Dinge beachten: ein wenig Konfiguration und die passende Hilfsbibliothek. Manche Dinge funktionieren nicht direkt out of the box, deshalb lohnt sich ein Blick in die Konfigurationsmöglichkeiten.

Die klarere Empfehlung betrifft die Testing Library für Cypress. Mit ihr schreibst du Tests aus Benutzersicht statt über DOM-Pfade. Du suchst einen Button mit bestimmter Test-ID oder mit einem bestimmten Label, oder ein Eingabefeld mit einem bestimmten Label.

Diese Schreibweise ist intuitiver und die resultierenden Tests sind deutlich stabiler. Die Migration zwischen Versionen ist einfach, solange du sie laufend mitmachst. Was du vermeiden solltest: Updates lange liegen lassen und Migrationsschritte überspringen.

Diese Seite teilen

Ähnliche Beiträge