Was ist Cypress?
Cypress ist ein modernes, JavaScript-basiertes Test-Framework, das speziell für Webanwendungen entwickelt wurde. Anders als ältere Lösungen läuft Cypress direkt im Browser – nicht durch einen externen Treiber –, was die Ausführung deutlich schneller und zuverlässiger macht. Das Tool wurde 2017 veröffentlicht und hat sich seitdem zum De-facto-Standard für End-to-End-Tests in der JavaScript-Welt etabliert.
Cypress unterstützt sowohl End-to-End-Tests als auch Component Tests und bietet eine interaktive Benutzeroberfläche, in der Entwicklerinnen und Entwickler jeden Testschritt in Echtzeit verfolgen können. Die enge Integration in den Browser erlaubt es, Netzwerkanfragen abzufangen, den DOM zu manipulieren und auf interne Anwendungszustände zuzugreifen – Möglichkeiten, die mit klassischen Selenium-basierten Ansätzen schwer umsetzbar sind.
E2E-Tests vs. Unit-Tests: Was ist der Unterschied?
Unit-Tests überprüfen einzelne Funktionen oder Komponenten isoliert von ihrer Umgebung. Sie sind schnell, einfach zu schreiben und bilden die Basis einer soliden Teststrategie. E2E-Tests hingegen simulieren das vollständige Nutzerverhalten: Sie öffnen den Browser, navigieren durch die Anwendung, füllen Formulare aus und prüfen, ob das Ergebnis den Erwartungen entspricht.
Das klassische Testpyramiden-Modell empfiehlt viele Unit-Tests, einige Integrationstests und wenige E2E-Tests. Cypress bedient vor allem die oberen Schichten dieser Pyramide. Gerade bei komplexen Formularen, Multi-Step-Workflows oder Authentifizierungsabläufen sind E2E-Tests unverzichtbar, um Regressionsfehler frühzeitig zu erkennen.
Der Cypress Test Runner: Interaktive Entwicklung
Einer der größten Vorteile von Cypress gegenüber anderen Frameworks ist der interaktive Test Runner. Beim Ausführen von npx cypress open öffnet sich eine grafische Oberfläche, in der alle Testdateien aufgelistet sind. Ein Klick startet den Test in einem echten Browser-Fenster.
Im Test Runner sieht man auf der linken Seite jeden einzelnen Befehl mit seinem Status. Bei einem Hover über einen Befehl springt die rechte Seite zum entsprechenden DOM-Zustand – einem sogenannten Time Travel Snapshot. Das macht die Fehlersuche erheblich einfacher als das bloße Lesen von Stack Traces. Zusätzlich lassen sich Screenshots und Videos automatisch aufzeichnen.
Grundlegende Cypress-Befehle
Die wichtigsten Befehle für den Einstieg sind überschaubar:
cy.visit('/login')– Navigiert zu einer URL relativ zur konfiguriertenbaseUrl.cy.get('[data-cy="email"]')– Selektiert ein DOM-Element. Cypress empfiehlt datenattributbasierte Selektoren für stabilere Tests.cy.contains('Anmelden')– Findet ein Element anhand seines Textinhalts.cy.click()– Klickt auf das aktuell selektierte Element.cy.type('[email protected]')– Gibt Text in ein Eingabefeld ein.cy.should('be.visible')– Prüft eine Bedingung (Assertion).
Ein typischer Login-Test könnte so aussehen: cy.visit('/login'), dann cy.get('[data-cy="email"]').type('[email protected]'), cy.get('[data-cy="password"]').type('geheimwort') und cy.get('[data-cy="submit"]').click(). Anschließend prüft man mit cy.url().should('include', '/dashboard'), ob die Weiterleitung korrekt erfolgt ist.
Fixtures und cy.intercept: Netzwerkanfragen kontrollieren
In realen Tests möchte man oft nicht gegen echte APIs testen. Mit Fixtures lassen sich statische JSON-Dateien im Ordner cypress/fixtures/ ablegen und als Testdaten verwenden. Der Befehl cy.fixture('benutzer.json') lädt diese Datei und stellt sie im Test bereit.
cy.intercept() ist das mächtige Werkzeug, um HTTP-Anfragen abzufangen und durch Mock-Daten zu ersetzen. Ein Beispiel: cy.intercept('GET', '/api/users', { fixture: 'users.json' }).as('getUsers') fängt alle GET-Anfragen an /api/users ab und antwortet mit der Fixture-Datei. Mit cy.wait('@getUsers') kann man explizit warten, bis diese Anfrage abgeschlossen ist – das verhindert flaky Tests durch Timing-Probleme.
data-cy-Attribut statt CSS-Klassen oder IDs als Selektor. Klassen und IDs ändern sich häufig bei Refactoring, während Test-Attribute stabil bleiben. Eine Konvention wie data-cy="login-submit-button" macht Tests lesbar und wartbar zugleich.
Component Testing mit Cypress
Seit Version 10 bietet Cypress auch Component Testing für React, Vue, Angular und Svelte. Dabei wird die Komponente direkt im Browser gemountet, ohne die gesamte Anwendung zu starten. Das ist schneller als ein vollständiger E2E-Test und präziser als ein reiner Unit-Test mit jsdom.
Component Tests werden in der gleichen Syntax geschrieben wie E2E-Tests. Der Befehl cy.mount(<MeinButton label="Klick mich" />) rendert die Komponente. Danach kann man mit gewohnten Cypress-Befehlen interagieren und Assertions schreiben. Gerade für Bibliothekskomponenten oder Design-System-Elemente ist dieser Ansatz sehr wertvoll.
CI-Integration
Cypress lässt sich nahtlos in alle gängigen CI/CD-Systeme integrieren. Der Befehl npx cypress run führt alle Tests ohne grafische Oberfläche aus und gibt einen Exit-Code zurück – ideal für Pipelines. Mit dem offiziellen Cypress GitHub Action ist die Einrichtung in GitHub Actions in wenigen Zeilen erledigt.
Der kommerzielle Cypress Cloud-Dienst bietet darüber hinaus parallele Testausführung, Testergebnisanalysen und Flaky-Test-Erkennung. Für Open-Source-Projekte ist er kostenlos nutzbar.
Vergleich: Cypress vs. Playwright vs. Selenium vs. WebdriverIO
| Kriterium | Cypress | Playwright | Selenium | WebdriverIO |
|---|---|---|---|---|
| Ausführungsgeschwindigkeit | Schnell (im Browser) | Sehr schnell | Langsam (WebDriver) | Mittel |
| Developer Experience | Sehr gut | Sehr gut | Mäßig | Gut |
| Browser-Unterstützung | Chrome, Firefox, Edge | Alle inkl. Safari/WebKit | Alle Browser | Alle Browser |
| Parallele Ausführung | Kostenpflichtig (Cloud) | Kostenlos eingebaut | Möglich (Selenium Grid) | Möglich |
| Component Testing | Ja (seit v10) | Experimentell | Nein | Nein |
| Sprachen | JavaScript/TypeScript | JS/TS, Python, Java, C# | Viele Sprachen | JavaScript/TypeScript |
| Einstiegshürde | Niedrig | Niedrig | Hoch | Mittel |
FAQ zu Cypress
- Kann Cypress mehrere Browser-Tabs gleichzeitig steuern?
- Nein, Cypress unterstützt keine Multi-Tab-Szenarien. Das ist eine bewusste Designentscheidung. Workflows, die mehrere Tabs erfordern, sollten durch direkte URL-Navigation oder API-Aufrufe simuliert werden. Für echte Multi-Tab-Tests ist Playwright besser geeignet.
- Wie unterscheidet sich
cy.get()voncy.find()? cy.get()sucht global im gesamten DOM, währendcy.find()innerhalb eines bereits selektierten Elements sucht.cy.find()ist also ein scoped Query, der nach einemcy.get()eingesetzt wird, um die Suche auf einen Teilbaum einzuschränken.- Was sind flaky Tests und wie verhindert Cypress sie?
- Flaky Tests sind Tests, die mal bestehen und mal fehlschlagen, ohne dass sich der Code geändert hat – oft durch Timing-Probleme. Cypress wartet automatisch bis zu 4 Sekunden auf DOM-Elemente und Assertions. Mit
cy.intercept().as()undcy.wait()lassen sich Netzwerkabhängigkeiten explizit abwarten. - Ist Cypress für das Testen von Mobile Apps geeignet?
- Cypress ist ausschließlich für Webanwendungen im Browser ausgelegt. Für native Mobile Apps (iOS/Android) eignet sich Cypress nicht. Für mobile Web-Ansichten kann man jedoch die Browser-Fenstergröße auf typische Smartphone-Dimensionen setzen und so responsive Layouts testen.
Weiterführende Informationen finden sich in der offiziellen Cypress-Dokumentation.