Cypress oder Playwright: woran die Wahl wirklich hängt
Der Unterschied steckt nicht in der Schreibweise der Kommandos, sondern darin, ob der Test im Browser mitläuft oder ihn von außen steuert.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Rote Tests, die niemand mehr ernst nimmt, sind teurer als gar keine Tests
Eine Oberflächensuite wächst selten geplant. Erst sind es fünf Abläufe für die Anmeldung, dann kommen Warenkorb und Formularvalidierung dazu, und irgendwann läuft die Suite länger als der Rest der Pipeline zusammen. Parallel dazu fangen zwei, drei Tests an, sporadisch rot zu werden. Der erste Reflex ist ein Wiederholungsversuch in der Konfiguration, der zweite ein zweiter, und ab da schaut niemand mehr in den Bericht.
Der Schaden ist nicht die verlorene Rechenzeit, sondern das verlorene Signal. Wenn drei von zweihundert Tests immer mal rot sind, wird jeder rote Lauf zuerst als Wackler eingeordnet. Genau darin verschwindet die eine echte Regression, die die Suite hätte finden sollen. Die Suite läuft weiter, kostet weiter und schützt nicht mehr.
Das Werkzeug repariert keinen schlecht geschriebenen Test. Es entscheidet aber darüber, wie viel Arbeit es ist, die Ursache zu finden, wenn ein Test nur auf dem Bauserver rot wird: ob du eine begehbare Aufzeichnung des fehlgeschlagenen Laufs mit dem DOM zu jedem Schritt hast oder ein Video und einen Screenshot von dem Moment, in dem schon alles vorbei war.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Der direkte Vergleich
Cypress
Der Testcode läuft im Browser neben der Anwendung, der mitgelieferte Runner zeigt jeden Schritt live
Playwright
Ein Node-Prozess steuert Chromium, Firefox und WebKit über deren Protokoll von außen
| Entscheidungsfrage | Cypress | Playwright |
|---|---|---|
| Welche Browser deckt ein Lauf ab? | Kommt darauf an Chromium-basierte Browser und Firefox laufen zuverlässig. Für WebKit, also die Grundlage von Safari, ist die Unterstützung eingeschränkt, was ausgerechnet auf iOS zur Lücke wird. | Stärke Chromium, Firefox und WebKit werden als eigene Builds mitgeliefert und mit jeder Version aktualisiert. Derselbe Test läuft ohne Änderung in allen drei Motoren. |
| Wie geht das Werkzeug mit Wartezeiten um? | Kommt darauf an Die letzte Anweisung einer Kette wird wiederholt, solange eine Zusicherung daran hängt. Sobald du einen Wert mit .then aus der Kette holst, ist er ein Schnappschuss und nach einem Neuaufbau des DOM veraltet. | Stärke Ein Locator ist eine Beschreibung, kein Element, und löst bei jeder Verwendung neu auf. Zusicherungen wie toBeVisible wiederholen bis zur Frist, und vor jedem Klick prüft Playwright Sichtbarkeit, Stabilität und Erreichbarkeit. |
| Wie lange läuft eine große Suite in der Pipeline? | Kommt darauf an Innerhalb eines Laufs arbeitet Cypress die Dateien nacheinander ab. Verteilen auf mehrere Maschinen setzt Cypress Cloud oder einen selbst betriebenen Ersatzdienst voraus, sonst teilt ihr die Dateien von Hand auf mehrere Aufträge auf. | Stärke Mehrere Worker arbeiten von Haus aus parallel, und eine Option zerlegt die Suite in Teilmengen für mehrere Maschinen. Die Teilberichte lassen sich anschließend zu einem einzigen Bericht zusammenführen. |
| Wie findest du heraus, warum ein Test nur auf dem Bauserver rot wird? | Kommt darauf an Aus dem Lauf bleiben ein Video und ein Screenshot des Fehlschlags. Die Zeitreise durch die einzelnen Kommandos gibt es im Runner, also lokal, nicht im fertigen Bericht der Pipeline. | Stärke Der Trace enthält zu jedem Schritt einen DOM-Stand, dazu Netzwerkverkehr, Konsolenausgaben und die Quellzeile. Du klickst den fehlgeschlagenen Lauf nachträglich im Browser durch, ohne ihn zu wiederholen. |
| Wie schnell ist ein Team ohne Erfahrung produktiv? | Stärke Ein einziger Kommandostil, kein await, und der Runner zeigt beim Schreiben live, was passiert. Wer HTML und CSS-Selektoren kennt, schreibt am ersten Tag brauchbare Tests. | Kommt darauf an Async und await ziehen sich durch jeden Test, dazu kommen Fixtures, Projekte und eine breite Konfigurationsfläche. Der Aufzeichnungsmodus hilft beim Start, die Konzepte muss man trotzdem verstehen. |
| Was ist mit mehreren Fenstern, Rollen und fremden Domänen? | Schwäche Ein zweites Browserfenster ist nicht vorgesehen. Für den Wechsel auf eine andere Domäne gibt es cy.origin, das den betreffenden Testcode in einem eigenen Block ausführt, mit Einschränkungen bei dem, was du hineinreichen kannst. | Stärke Mehrere Kontexte in einem Browser sind der Normalfall und kosten fast nichts. Zwei angemeldete Rollen im selben Test, ein zweites Fenster und ein Wechsel der Domäne sind gewöhnliche Abläufe. |
| Wie kommt ein Test an den Zustand der laufenden Anwendung heran? | Stärke Der Testcode sitzt im selben Fenster wie die Anwendung. Über cy.window erreichst du einen Speicher, den Router oder eine Hilfsfunktion direkt und kannst einen Ausgangszustand setzen, statt ihn zu erklicken. | Schwäche Alles, was die Prozessgrenze überquert, muss serialisierbar sein. page.evaluate liefert dir zurück, was sich als JSON darstellen lässt, kein DOM-Element und keine Klasseninstanz. Wer den Zustand der Anwendung im Test lesen oder setzen will, braucht dafür eine eigene Brücke im Anwendungscode. |
Welche Browser deckt ein Lauf ab?
Chromium-basierte Browser und Firefox laufen zuverlässig. Für WebKit, also die Grundlage von Safari, ist die Unterstützung eingeschränkt, was ausgerechnet auf iOS zur Lücke wird.
Chromium, Firefox und WebKit werden als eigene Builds mitgeliefert und mit jeder Version aktualisiert. Derselbe Test läuft ohne Änderung in allen drei Motoren.
Wie geht das Werkzeug mit Wartezeiten um?
Die letzte Anweisung einer Kette wird wiederholt, solange eine Zusicherung daran hängt. Sobald du einen Wert mit .then aus der Kette holst, ist er ein Schnappschuss und nach einem Neuaufbau des DOM veraltet.
Ein Locator ist eine Beschreibung, kein Element, und löst bei jeder Verwendung neu auf. Zusicherungen wie toBeVisible wiederholen bis zur Frist, und vor jedem Klick prüft Playwright Sichtbarkeit, Stabilität und Erreichbarkeit.
Wie lange läuft eine große Suite in der Pipeline?
Innerhalb eines Laufs arbeitet Cypress die Dateien nacheinander ab. Verteilen auf mehrere Maschinen setzt Cypress Cloud oder einen selbst betriebenen Ersatzdienst voraus, sonst teilt ihr die Dateien von Hand auf mehrere Aufträge auf.
Mehrere Worker arbeiten von Haus aus parallel, und eine Option zerlegt die Suite in Teilmengen für mehrere Maschinen. Die Teilberichte lassen sich anschließend zu einem einzigen Bericht zusammenführen.
Wie findest du heraus, warum ein Test nur auf dem Bauserver rot wird?
Aus dem Lauf bleiben ein Video und ein Screenshot des Fehlschlags. Die Zeitreise durch die einzelnen Kommandos gibt es im Runner, also lokal, nicht im fertigen Bericht der Pipeline.
Der Trace enthält zu jedem Schritt einen DOM-Stand, dazu Netzwerkverkehr, Konsolenausgaben und die Quellzeile. Du klickst den fehlgeschlagenen Lauf nachträglich im Browser durch, ohne ihn zu wiederholen.
Wie schnell ist ein Team ohne Erfahrung produktiv?
Ein einziger Kommandostil, kein await, und der Runner zeigt beim Schreiben live, was passiert. Wer HTML und CSS-Selektoren kennt, schreibt am ersten Tag brauchbare Tests.
Async und await ziehen sich durch jeden Test, dazu kommen Fixtures, Projekte und eine breite Konfigurationsfläche. Der Aufzeichnungsmodus hilft beim Start, die Konzepte muss man trotzdem verstehen.
Was ist mit mehreren Fenstern, Rollen und fremden Domänen?
Ein zweites Browserfenster ist nicht vorgesehen. Für den Wechsel auf eine andere Domäne gibt es cy.origin, das den betreffenden Testcode in einem eigenen Block ausführt, mit Einschränkungen bei dem, was du hineinreichen kannst.
Mehrere Kontexte in einem Browser sind der Normalfall und kosten fast nichts. Zwei angemeldete Rollen im selben Test, ein zweites Fenster und ein Wechsel der Domäne sind gewöhnliche Abläufe.
Wie kommt ein Test an den Zustand der laufenden Anwendung heran?
Der Testcode sitzt im selben Fenster wie die Anwendung. Über cy.window erreichst du einen Speicher, den Router oder eine Hilfsfunktion direkt und kannst einen Ausgangszustand setzen, statt ihn zu erklicken.
Alles, was die Prozessgrenze überquert, muss serialisierbar sein. page.evaluate liefert dir zurück, was sich als JSON darstellen lässt, kein DOM-Element und keine Klasseninstanz. Wer den Zustand der Anwendung im Test lesen oder setzen will, braucht dafür eine eigene Brücke im Anwendungscode.
Was passt wann
- Ihr fangt einen neuen Bestand an Oberflächentests an
- Playwright, und zwar von Anfang an mit gespeichertem Anmeldezustand und einer Aufzeichnung, die nur beim ersten Wiederholungsversuch geschrieben wird.
- Eine gewachsene Cypress-Suite läuft und die Laufzeit stört niemanden
- Bestand lassen. Ein Umstieg kostet in den ersten Monaten mehr Zeit, als er an Laufzeit einspart, und der Nutzen kommt erst danach.
- Die Suite dauert länger als der Rest der Pipeline und Safari fehlt in der Abdeckung
- Neue Abläufe in Playwright schreiben, den Cypress-Bestand einfrieren und nur bei Änderungen an den betroffenen Seiten mitziehen.
Sechs Fragen, die die Wahl entscheiden
- 01 Muss die Anwendung auch in Safari laufen? Playwright bringt WebKit mit.
- 02 Wechselt ein Ablauf auf eine fremde Domäne, etwa zur Bezahlung? Das spricht für Playwright.
- 03 Braucht ein Test zwei Fenster oder zwei angemeldete Rollen gleichzeitig? Ebenfalls Playwright.
- 04 Läuft die Suite heute in Cypress und stört niemanden? Dann bleibt sie, wo sie ist.
- 05 Soll ein Team ohne Erfahrung mit await starten? Cypress ist der kürzere Weg.
- 06 Wird die Laufzeit zum Problem? Playwright verteilt ohne Zusatzdienst auf mehrere Prozesse.
Was du entscheiden kannst, ohne beide Werkzeuge auszuprobieren
Die Kommandos beider Werkzeuge sehen sich ähnlich genug, dass ein Vergleich der Syntax nichts austrägt. Der Unterschied sitzt eine Ebene tiefer, in der Frage, wo der Testcode ausgeführt wird. Aus dieser einen Entscheidung folgen Browserabdeckung, der Umgang mit mehreren Fenstern, das Verhalten bei Wartezeiten und die Art der Fehlersuche.
Die Bauart auseinanderhalten
Cypress führt den Testcode im Browser aus, direkt neben der Anwendung. Playwright führt ihn in einem Node-Prozess aus und steuert den Browser über dessen Protokoll. Fast jeder Unterschied in der Vergleichstabelle lässt sich auf diesen Satz zurückführen.
Wartezeiten nicht mehr mit festen Sekunden zupflastern
Beide Werkzeuge warten von sich aus, aber auf verschiedene Dinge. Du lernst, welche Anweisung wiederholt wird und welche nur einmal läuft, und ersetzt jede feste Wartezeit durch eine Bedingung, die den erwarteten Zustand benennt.
Laufzeit über mehrere Prozesse verteilen
Playwright startet mehrere Worker und teilt die Suite mit einer Option auf mehrere Maschinen auf. Cypress arbeitet innerhalb eines Laufs die Dateien nacheinander ab; die Verteilung läuft über Cypress Cloud oder über einen selbst betriebenen Ersatzdienst.
Rote Läufe im Bauserver ohne Ratespiel klären
Eine Aufzeichnung mit DOM-Ständen, Netzwerkverkehr und Konsolenausgaben beantwortet die Frage nach der Ursache in Minuten. Video und Screenshot beantworten sie oft gar nicht, weil beide erst nach dem Fehlschlag entstehen.
Die Anmeldung einmal erledigen statt in jedem Test
Der Anmeldevorgang durch die Oberfläche ist in einer Suite mit zweihundert Tests der größte einzelne Zeitposten. Playwright speichert den angemeldeten Zustand und lädt ihn, Cypress hat für denselben Zweck cy.session.
Den Einstieg realistisch ansetzen
Cypress verlangt kein Verständnis von await, weil die Kommandokette in eine Warteschlange geschrieben wird. Playwright verlangt es überall, gibt dafür aber gewöhnliches JavaScript zurück, mit dem sich normal rechnen lässt.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Zwei Bauarten, und daraus folgt fast alles andere
Cypress führt den Testcode im Browser aus, in einem Rahmen neben der Anwendung. Das bringt zwei echte Vorteile: Der Test kann ohne Umweg auf Objekte der Anwendung zugreifen, etwa mit cy.window und dem Zugriff auf einen Store, und der Runner kann jeden Schritt zeigen, weil er im selben Prozess sitzt. Der Preis ist ebenso direkt: Was der Browser einer Seite verbietet, verbietet er auch dem Test. Deshalb ein Tab, deshalb der Sonderweg über cy.origin bei einem Wechsel der Domäne.
Playwright läuft in einem Node-Prozess und spricht mit dem Browser über dessen Steuerprotokoll. Der Testcode ist nie Teil der Seite. Daraus folgt, dass mehrere Kontexte in einem Browser laufen können, also mehrere voneinander unabhängige Sitzungen mit eigenen Cookies und eigenem Speicher, ohne dass für jede ein neuer Browserprozess starten müsste. Ein zweites Fenster, eine zweite Rolle oder eine fremde Domäne sind damit keine Sonderfälle, sondern nur weitere Kontexte.
Für den Testcode selbst heißt das: Bei Cypress darfst du in die Anwendung hineingreifen, bei Playwright muss alles, was die Prozessgrenze überquert, serialisierbar sein. page.evaluate gibt dir zurück, was sich als JSON darstellen lässt, kein DOM-Element und keine Klasseninstanz. Das klingt nach einer Einschränkung, hält aber Tests davon ab, sich an Interna zu binden, die sich beim nächsten Umbau ändern.
Wackelige Tests: worauf beide Werkzeuge tatsächlich warten
Keines der beiden Werkzeuge wartet darauf, dass die Seite fertig ist, weil es diesen Zustand in einer Anwendung mit laufenden Abfragen nicht gibt. Playwright prüft vor jeder Aktion eine Reihe von Bedingungen: Ist das Element im DOM, sichtbar, seit zwei Bildern an derselben Stelle, nicht von etwas anderem verdeckt und bedienbar. Erst dann klickt es. Zusicherungen wie toHaveText wiederholen bis zur Frist, statt einmal zu prüfen und zu scheitern.
Cypress wiederholt die jeweils letzte Anweisung einer Kette, solange eine Zusicherung daran hängt. Genau daran hängt auch die häufigste Ursache für wackelige Tests: Sobald du mit .then einen Wert aus der Kette holst und ihn später verwendest, ist er ein Schnappschuss. Wird die Liste in der Zwischenzeit neu gerendert, zeigt deine Variable auf ein Element, das nicht mehr im Dokument hängt, und der Klick geht ins Leere. Der richtige Ersatz für cy.wait mit einer festen Zahl ist nicht eine größere Zahl, sondern cy.intercept mit einem Namen und cy.wait auf diesen Namen.
Es gibt eine dritte Gruppe von Ursachen, die kein Werkzeug löst: eine Animation, die das Element noch bewegt, ein Autofokus, der den Cursor wegzieht, eine Liste, deren Reihenfolge die Schnittstelle nicht garantiert, und Testdaten, die von der Uhrzeit abhängen. Ein Test, der solche Fälle überlebt, benennt seine Erwartung genau: nicht das dritte Element in der Liste, sondern die Zeile mit dieser Bestellnummer.
Laufzeit in der Pipeline
Playwright startet standardmäßig mehrere Worker, führt bei entsprechender Einstellung auch Tests innerhalb einer Datei parallel aus und zerlegt die Suite über eine Option in Teilmengen, die auf getrennten Maschinen laufen. Die Teilberichte lassen sich anschließend zu einem HTML-Bericht zusammenführen. Wichtig dabei: Die Anwendung sollte einmal gebaut und als Artefakt weitergereicht werden, sonst baut jede Teilmenge sie erneut und frisst den Gewinn wieder auf.
Cypress arbeitet die Dateien innerhalb eines Laufs nacheinander ab. Die eingebaute Verteilung mit Lastausgleich läuft über Cypress Cloud, alternativ über einen selbst betriebenen Ersatzdienst. Der billigere erste Schritt ohne beides: die Testdateien von Hand auf mehrere Aufträge im Bauserver verteilen. Das ist grob, holt aber den größten Teil der möglichen Verkürzung.
Der größere Hebel liegt in beiden Fällen woanders: Nicht jeder Schritt muss durch die Oberfläche laufen. Die Anmeldung wird einmal über die Schnittstelle erledigt und der Zustand gespeichert, Testdaten werden über die Schnittstelle angelegt statt über fünf Formulare. Playwright bietet dafür eine eigene Anfrage-Fixture und den gespeicherten Anmeldezustand, Cypress cy.request zusammen mit cy.session. In einer Suite mit zweihundert Tests spart das mehr als jede Parallelisierung.
Fehlersuche, wenn es nur auf dem Bauserver rot wird
Playwright schreibt auf Wunsch einen Trace, sinnvollerweise nur beim ersten Wiederholungsversuch, damit grüne Läufe nichts kosten. Der Trace enthält zu jedem Schritt einen Stand des DOM, dazu Netzwerkverkehr, Konsolenausgaben und die Zeile im Quelltext. Im Trace Viewer klickst du den Lauf nachträglich durch und siehst, wie die Seite im Moment des Fehlschlags aussah, nicht wie sie eine Sekunde später aussah.
Cypress liefert aus einem Lauf in der Pipeline ein Video und einen Screenshot des Fehlschlags. Die Zeitreise mit den Zwischenständen je Kommando gibt es im Runner, also während der lokalen Arbeit. Für viele Fälle reicht das Video, für die Fälle, in denen der Unterschied zwischen Bauserver und lokalem Rechner der eigentliche Punkt ist, reicht es selten.
Für beide gilt dieselbe Regel: Ein Wiederholungsversuch, der den Test grün macht, versteckt die Ursache. Wiederholungen sind eine Brücke, keine Lösung, und ihre Anzahl gehört in den Bericht, damit sichtbar bleibt, welche Tests sie brauchen. Wenn derselbe Test dreimal in einer Woche nur im zweiten Anlauf grün wird, ist er die nächste Aufgabe und nicht das nächste Ärgernis.
Umstieg, Nebeneinander oder gar nicht
Beide Werkzeuge lassen sich in einem Repository nebeneinander betreiben, in getrennten Verzeichnissen und mit getrennten Aufträgen im Bauserver. Teuer ist beim Umstieg nicht die Syntax, sondern alles daneben: die Hilfsfunktionen für Seitenbereiche, die Testdaten, die Anmeldung und die Erwartungen an die Umgebung. Wer umstellt, plant diese vier Punkte zuerst und übersetzt danach Tests.
Wenn ihr migriert, fangt mit den Tests an, die am häufigsten rot werden. Dort ist der Gewinn am größten, und dort merkt ihr am schnellsten, ob das neue Werkzeug die Ursache tatsächlich sichtbar macht. Eine Eins-zu-eins-Übersetzung jedes Kommandos lohnt nicht, weil sich beim Umstieg vor allem die Art der Auswahl ändert.
Playwright legt getByRole nahe, also die Auswahl über die Rolle eines Elements und seinen zugänglichen Namen, genau das, was auch ein Screenreader vorliest. Das hat einen Nebeneffekt, der über das Testen hinausgeht: Ein Element, das sich so nicht auswählen lässt, hat meist auch für unterstützende Technik keinen brauchbaren Namen. Der Test wird damit zur Nebenprüfung für die Zugänglichkeit.
Dazu passende Kurse
In den JavaScript-Kursen bei cmt lernst du zwei Werkzeuge für Tests durch die Oberfläche an derselben Anwendung kennen und vergleichst sie an eurem eigenen Ablauf.
Testwerkzeuge sind nur ein Baustein, die übrigen Themen der Webentwicklung decken Aufbau, Gestaltung und Auslieferung mit ab.
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.
Ein sehr gutes, praxisorientiertes und nachhaltiges Seminar. So sollte es immer sein. Vielen Dank.
Die Schulung ist gerade für Einsteiger oder Entwickler*innen mit eingestaubtem Basiswissen sehr hilfreich.
Ich bin sehr glücklich Franz als Trainer gehabt zu haben. Er hat offensichtlich unglaublich viel Wissen zu den Themen, und schafft es, dieses auch interaktiv und verständlich weiterzugeben.
Häufige Fragen
Braucht Playwright zwingend TypeScript?
Können die beiden auch Komponenten testen?
Ersetzen Oberflächentests die Unit-Tests?
Und was ist mit Selenium?
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 Webentwicklung-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.
Oberflächentests, die beim nächsten Umbau nicht reihenweise rot werden
In den Testkursen bei cmt schreibst du dieselbe Strecke in beiden Werkzeugen und siehst dabei, an welchen Stellen die Unterschiede im Alltag wirklich auftauchen.