Ein umfassender Leitfaden zum Cypress E2E-Testing-Framework: Installation, Testentwicklung, Debugging, CI/CD-Integration und Best Practices.
Cypress: Der ultimative Leitfaden für End-to-End-Tests von Webanwendungen
In der heutigen, sich schnell entwickelnden Webentwicklungslandschaft ist die Sicherstellung der Qualität und Zuverlässigkeit von Webanwendungen von größter Bedeutung. End-to-End (E2E)-Tests spielen eine entscheidende Rolle bei der Überprüfung, ob alle Komponenten einer Anwendung aus der Perspektive des Benutzers nahtlos zusammenarbeiten. Cypress hat sich als führendes E2E-Testing-Framework etabliert und bietet eine entwicklerfreundliche Erfahrung, leistungsstarke Funktionen und eine hervorragende Performance. Dieser umfassende Leitfaden führt Sie durch alles, was Sie wissen müssen, um mit Cypress zu beginnen und Ihre Webanwendungen effektiv zu testen.
Was ist Cypress?
Cypress ist ein Frontend-Testing-Tool der nächsten Generation, das für das moderne Web entwickelt wurde. Im Gegensatz zu traditionellen Test-Frameworks, die Tests in einem Browser ausführen, arbeitet Cypress direkt im Browser, was Ihnen eine beispiellose Kontrolle und Einblick in das Verhalten Ihrer Anwendung gibt. Es ist so konzipiert, dass es schnell, zuverlässig und einfach zu bedienen ist, was es zu einer beliebten Wahl bei Entwicklern und QA-Ingenieuren weltweit macht. Cypress ist in JavaScript geschrieben und wird innerhalb des Browsers ausgeführt, was es sehr performant macht und einen unvergleichlichen Zugriff auf die Interna der Anwendung bietet.
Wichtige Vorteile der Verwendung von Cypress
- Entwicklerfreundlich: Cypress bietet eine saubere und intuitive API, die das Schreiben und Debuggen von Tests erleichtert.
- Zeitreise (Time Travel): Cypress erstellt während jedes Testbefehls Snapshots des Zustands Ihrer Anwendung, sodass Sie in der Zeit zurückgehen und genau sehen können, was zu jedem Zeitpunkt passiert ist.
- Echtzeit-Neuladen: Cypress lädt automatisch neu, wenn Sie Änderungen an Ihren Tests vornehmen, und liefert sofortiges Feedback.
- Automatisches Warten: Cypress wartet automatisch darauf, dass Elemente sichtbar oder interaktiv werden, bevor es Aktionen ausführt, wodurch die Notwendigkeit expliziter Wartezeiten entfällt.
- Netzwerkkontrolle: Cypress ermöglicht es Ihnen, Netzwerkanfragen und -antworten zu stubben, sodass Sie verschiedene Szenarien simulieren und die Fehlerbehandlung Ihrer Anwendung testen können.
- Debug-Fähigkeit: Cypress bietet hervorragende Debugging-Tools, einschließlich eines leistungsstarken Debuggers und detaillierter Fehlermeldungen.
- Cross-Browser-Testing: Cypress unterstützt mehrere Browser, einschließlich Chrome, Firefox, Edge und Electron.
- Headless-Testing: Führen Sie Tests im Headless-Modus für eine schnellere Ausführung in CI/CD-Umgebungen aus.
- Integrierte Assertions: Cypress bietet eine Vielzahl integrierter Assertions, um das erwartete Verhalten Ihrer Anwendung zu überprüfen.
Installation und Einrichtung
Der Einstieg in Cypress ist unkompliziert. So installieren Sie es:
- Voraussetzungen: Stellen Sie sicher, dass Node.js und npm (Node Package Manager) auf Ihrem System installiert sind. Sie können sie von der offiziellen Node.js-Website herunterladen.
- Cypress installieren: Öffnen Sie Ihr Terminal oder Ihre Kommandozeile, navigieren Sie zu Ihrem Projektverzeichnis und führen Sie den folgenden Befehl aus:
- Cypress öffnen: Sobald die Installation abgeschlossen ist, können Sie den Cypress Test Runner mit folgendem Befehl öffnen:
npm install cypress --save-dev
npx cypress open
Dieser Befehl startet den Cypress Test Runner, der eine grafische Oberfläche zum Ausführen und Debuggen Ihrer Tests bietet.
Ihren ersten Cypress-Test schreiben
Erstellen wir einen einfachen Test, um zu überprüfen, ob die Startseite einer Website korrekt geladen wird. Erstellen Sie eine neue Datei mit dem Namen `example.cy.js` im Verzeichnis `cypress/e2e` Ihres Projekts.
// cypress/e2e/example.cy.js
describe('Mein erster Test', () => {
it('Besucht die Kitchen Sink', () => {
cy.visit('https://example.cypress.io')
cy.contains('type').click()
cy.url().should('include', '/commands/actions')
cy.get('.action-email')
.type('fake@email.com')
.should('have.value', 'fake@email.com')
})
})
Lassen Sie uns diesen Test aufschlüsseln:
- `describe()`: Definiert eine Test-Suite, eine Sammlung zusammengehöriger Tests.
- `it()`: Definiert einen einzelnen Testfall innerhalb der Test-Suite.
- `cy.visit()`: Navigiert zur angegebenen URL.
- `cy.contains()`: Findet ein Element, das den angegebenen Text enthält.
- `.click()`: Klickt auf das ausgewählte Element.
- `cy.url()`: Ruft die aktuelle URL der Seite ab.
- `.should()`: Macht eine Assertion über den Zustand der Anwendung.
- `cy.get()`: Wählt ein Element mit einem CSS-Selektor aus.
- `.type()`: Gibt Text in das ausgewählte Element ein.
- `.should('have.value', 'fake@email.com')`: Überprüft, ob der Wert des Elements 'fake@email.com' entspricht.
Führen Sie diesen Test im Cypress Test Runner aus, um ihn in Aktion zu sehen. Sie sollten sehen, wie der Browser zur Cypress Kitchen Sink-Website navigiert, auf den Link "type" klickt und die URL überprüft.
Cypress-Befehle
Cypress bietet eine breite Palette von Befehlen zur Interaktion mit Ihrer Anwendung. Hier sind einige der am häufigsten verwendeten Befehle:
- `cy.visit(url)`: Navigiert zur angegebenen URL.
- `cy.get(selector)`: Wählt ein Element mit einem CSS-Selektor aus.
- `cy.contains(content)`: Wählt ein Element aus, das den angegebenen Text enthält.
- `cy.click()`: Klickt auf das ausgewählte Element.
- `cy.type(text)`: Gibt Text in das ausgewählte Element ein.
- `cy.clear()`: Leert den Inhalt eines Eingabe- oder Textbereich-Elements.
- `cy.submit()`: Sendet ein Formular ab.
- `cy.check()`: Aktiviert ein Kontrollkästchen oder einen Radio-Button.
- `cy.uncheck()`: Deaktiviert ein Kontrollkästchen.
- `cy.select(value)`: Wählt eine Option aus einem Dropdown-Menü aus.
- `cy.scrollTo(position)`: Scrollt die Seite zur angegebenen Position.
- `cy.trigger(event)`: Löst ein DOM-Ereignis auf dem ausgewählten Element aus.
- `cy.request(url, options)`: Macht eine HTTP-Anfrage an die angegebene URL.
- `cy.intercept(route, handler)`: Fängt HTTP-Anfragen ab, die der angegebenen Route entsprechen.
- `cy.wait(time)`: Wartet die angegebene Zeitspanne ab.
- `cy.reload()`: Lädt die aktuelle Seite neu.
- `cy.go(direction)`: Navigiert zur vorherigen oder nächsten Seite im Browserverlauf.
- `cy.url()`: Ruft die aktuelle URL der Seite ab.
- `cy.title()`: Ruft den Titel der Seite ab.
- `cy.window()`: Ruft das Window-Objekt ab.
- `cy.document()`: Ruft das Document-Objekt ab.
- `cy.viewport(width, height)`: Legt die Größe des Viewports fest.
Dies sind nur einige der vielen in Cypress verfügbaren Befehle. Eine vollständige Liste der Befehle und ihrer Optionen finden Sie in der Cypress-Dokumentation.
Assertions in Cypress
Assertions werden verwendet, um das erwartete Verhalten Ihrer Anwendung zu überprüfen. Cypress bietet eine umfangreiche Sammlung integrierter Assertions, mit denen Sie den Zustand von Elementen, die URL, den Titel und mehr überprüfen können. Assertions werden nach Cypress-Befehlen mit der Methode `.should()` verkettet.
Hier sind einige gängige Beispiele für Assertions:
- `.should('be.visible')`: Überprüft, ob ein Element sichtbar ist.
- `.should('not.be.visible')`: Überprüft, ob ein Element nicht sichtbar ist.
- `.should('be.enabled')`: Überprüft, ob ein Element aktiviert ist.
- `.should('be.disabled')`: Überprüft, ob ein Element deaktiviert ist.
- `.should('have.text', 'erwarteter Text')`: Überprüft, ob ein Element den angegebenen Text hat.
- `.should('contain', 'erwarteter Text')`: Überprüft, ob ein Element den angegebenen Text enthält.
- `.should('have.value', 'erwarteter Wert')`: Überprüft, ob ein Element den angegebenen Wert hat.
- `.should('have.class', 'erwartete Klasse')`: Überprüft, ob ein Element die angegebene Klasse hat.
- `.should('have.attr', 'Attributname', 'erwarteter Wert')`: Überprüft, ob ein Element das angegebene Attribut und den angegebenen Wert hat.
- `.should('have.css', 'CSS-Eigenschaft', 'erwarteter Wert')`: Überprüft, ob ein Element die angegebene CSS-Eigenschaft und den angegebenen Wert hat.
- `.should('have.length', erwartete Länge)`: Überprüft, ob ein Element die angegebene Länge hat (z. B. die Anzahl der Elemente in einer Liste).
Sie können auch benutzerdefinierte Assertions erstellen, die Ihren spezifischen Anforderungen entsprechen.
Best Practices für das Schreiben von Cypress-Tests
Die Einhaltung von Best Practices kann Ihnen helfen, wartbarere, zuverlässigere und effizientere Cypress-Tests zu schreiben. Hier sind einige Empfehlungen:
- Schreiben Sie klare und prägnante Tests: Jeder Test sollte sich auf eine bestimmte Funktionalität oder ein Szenario konzentrieren. Vermeiden Sie das Schreiben übermäßig komplexer Tests, die schwer zu verstehen und zu warten sind.
- Verwenden Sie aussagekräftige Testnamen: Geben Sie Ihren Tests beschreibende Namen, die klar angeben, was sie testen.
- Vermeiden Sie hartcodierte Werte: Verwenden Sie Variablen oder Konfigurationsdateien, um Werte zu speichern, die sich im Laufe der Zeit ändern können.
- Verwenden Sie benutzerdefinierte Befehle: Erstellen Sie benutzerdefinierte Befehle, um wiederverwendbare Logik zu kapseln und Ihre Tests lesbarer zu machen.
- Isolieren Sie Tests: Jeder Test sollte unabhängig von anderen Tests sein. Vermeiden Sie es, sich auf den Zustand der Anwendung aus früheren Tests zu verlassen.
- Räumen Sie nach den Tests auf: Setzen Sie den Zustand der Anwendung nach jedem Test zurück, um sicherzustellen, dass nachfolgende Tests von einem sauberen Zustand ausgehen.
- Verwenden Sie Daten-Attribute: Verwenden Sie Daten-Attribute (z. B. `data-testid`), um Elemente in Ihren Tests auszuwählen. Daten-Attribute ändern sich seltener als CSS-Klassen oder IDs, was Ihre Tests widerstandsfähiger gegen Änderungen an der Benutzeroberfläche macht.
- Vermeiden Sie explizite Wartezeiten: Cypress wartet automatisch darauf, dass Elemente sichtbar oder interaktiv werden. Vermeiden Sie die Verwendung expliziter Wartezeiten (z. B. `cy.wait()`), es sei denn, es ist absolut notwendig.
- Testen Sie Benutzerabläufe: Konzentrieren Sie sich auf das Testen von Benutzerabläufen anstatt einzelner Komponenten. Dies hilft Ihnen sicherzustellen, dass Ihre Anwendung aus der Perspektive des Benutzers korrekt funktioniert.
- Führen Sie Tests regelmäßig aus: Integrieren Sie Cypress-Tests in Ihre CI/CD-Pipeline und führen Sie sie regelmäßig aus, um Fehler frühzeitig im Entwicklungsprozess zu erkennen.
Fortgeschrittene Cypress-Techniken
Stubbing und Mocking
Cypress ermöglicht es Ihnen, Netzwerkanfragen und -antworten zu stubben, wodurch Sie verschiedene Szenarien simulieren und die Fehlerbehandlung Ihrer Anwendung testen können. Dies ist besonders nützlich für das Testen von Funktionen, die auf externe APIs oder Dienste angewiesen sind.
Um eine Netzwerkanfrage zu stubben, können Sie den Befehl `cy.intercept()` verwenden. Der folgende Code stubbt beispielsweise eine GET-Anfrage an `/api/users` und gibt eine Mock-Antwort zurück:
cy.intercept('GET', '/api/users', {
statusCode: 200,
body: [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' }
]
}).as('getUsers')
Sie können dann mit `cy.wait('@getUsers')` auf die abgefangene Anfrage warten und überprüfen, ob Ihre Anwendung die Mock-Antwort korrekt verarbeitet.
Arbeiten mit Local Storage und Cookies
Cypress bietet Befehle zur Interaktion mit Local Storage und Cookies. Sie können diese Befehle verwenden, um Local Storage und Cookies in Ihren Tests zu setzen, abzurufen und zu löschen.
Um ein Local-Storage-Element zu setzen, können Sie den Befehl `cy.window()` verwenden, um auf das Window-Objekt zuzugreifen, und dann die Methode `localStorage.setItem()` verwenden. Zum Beispiel:
cy.window().then((win) => {
win.localStorage.setItem('myKey', 'myValue')
})
Um ein Local-Storage-Element abzurufen, können Sie den Befehl `cy.window()` verwenden und dann die Methode `localStorage.getItem()` nutzen. Zum Beispiel:
cy.window().then((win) => {
const value = win.localStorage.getItem('myKey')
expect(value).to.equal('myValue')
})
Um ein Cookie zu setzen, können Sie den Befehl `cy.setCookie()` verwenden. Zum Beispiel:
cy.setCookie('myCookie', 'myCookieValue')
Um ein Cookie abzurufen, können Sie den Befehl `cy.getCookie()` verwenden. Zum Beispiel:
cy.getCookie('myCookie').should('have.property', 'value', 'myCookieValue')
Umgang mit Datei-Uploads
Cypress bietet ein Plugin namens `cypress-file-upload`, das Datei-Uploads in Ihren Tests vereinfacht. Um das Plugin zu installieren, führen Sie den folgenden Befehl aus:
npm install -D cypress-file-upload
Fügen Sie dann die folgende Zeile zu Ihrer Datei `cypress/support/commands.js` hinzu:
import 'cypress-file-upload';
Sie können dann den Befehl `cy.uploadFile()` verwenden, um eine Datei hochzuladen. Zum Beispiel:
cy.get('input[type="file"]').attachFile('example.txt')
Arbeiten mit IFrames
Das Testen von IFrames kann schwierig sein, aber Cypress bietet eine Möglichkeit, mit ihnen zu interagieren. Sie können den Befehl `cy.frameLoaded()` verwenden, um auf das Laden eines IFrames zu warten, und dann den Befehl `cy.iframe()` verwenden, um das Document-Objekt des IFrames zu erhalten.
cy.frameLoaded('#myIframe')
cy.iframe('#myIframe').find('button').click()
Cypress und Continuous Integration/Continuous Deployment (CI/CD)
Die Integration von Cypress in Ihre CI/CD-Pipeline ist entscheidend für die Sicherstellung der Qualität Ihrer Anwendung. Sie können Cypress-Tests im Headless-Modus in Ihrer CI/CD-Umgebung ausführen. So geht's:
- Cypress installieren: Stellen Sie sicher, dass Cypress als Abhängigkeit in Ihrem Projekt installiert ist.
- CI/CD konfigurieren: Konfigurieren Sie Ihre CI/CD-Pipeline so, dass Cypress-Tests nach jedem Build ausgeführt werden.
- Cypress headless ausführen: Verwenden Sie den Befehl `cypress run`, um Cypress-Tests im Headless-Modus auszuführen.
Beispiel für eine CI/CD-Konfiguration (mit GitHub Actions):
name: Cypress Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
cypress-run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- name: Install dependencies
run: npm install
- name: Cypress run
uses: cypress-io/github-action@v5
with:
start: npm start
wait-on: 'http://localhost:3000'
Diese Konfiguration führt Cypress-Tests aus, wann immer Code in den `main`-Branch gepusht oder ein Pull-Request gegen den `main`-Branch erstellt wird. Die `cypress-io/github-action` vereinfacht den Prozess der Ausführung von Cypress-Tests in GitHub Actions.
Debuggen von Cypress-Tests
Cypress bietet hervorragende Debugging-Tools, die Ihnen helfen, Probleme in Ihren Tests zu identifizieren und zu beheben. Hier sind einige Tipps zum Debuggen von Cypress-Tests:
- Verwenden Sie den Cypress Test Runner: Der Cypress Test Runner bietet eine visuelle Oberfläche zum Ausführen und Debuggen Ihrer Tests. Sie können Ihre Tests Befehl für Befehl durchgehen, den Zustand der Anwendung inspizieren und detaillierte Fehlermeldungen anzeigen.
- Verwenden Sie den `cy.pause()`-Befehl: Der `cy.pause()`-Befehl pausiert die Ausführung Ihres Tests und ermöglicht es Ihnen, den Zustand der Anwendung in den Entwicklertools des Browsers zu inspizieren.
- Verwenden Sie den `cy.debug()`-Befehl: Der `cy.debug()`-Befehl gibt das ausgewählte Element in der Konsole aus, sodass Sie dessen Eigenschaften und Attribute inspizieren können.
- Verwenden Sie die Entwicklertools des Browsers: Die Entwicklertools des Browsers bieten eine Fülle von Informationen über Ihre Anwendung, einschließlich des DOM, der Netzwerkanfragen und der Konsolenprotokolle.
- Lesen Sie Fehlermeldungen sorgfältig: Cypress liefert detaillierte Fehlermeldungen, die Ihnen helfen können, die Fehlerursache zu identifizieren. Achten Sie auf die Fehlermeldung und den Stack-Trace.
Cypress im Vergleich zu anderen Test-Frameworks
Obwohl Cypress ein leistungsstarkes End-to-End-Testing-Framework ist, ist es wichtig zu verstehen, wie es sich von anderen beliebten Optionen unterscheidet. Hier ist ein kurzer Überblick:
- Selenium: Selenium ist ein weit verbreitetes Framework für die Testautomatisierung. Obwohl es flexibel ist und mehrere Sprachen unterstützt, kann die Einrichtung und Wartung komplex sein. Cypress bietet eine einfachere und entwicklerfreundlichere Erfahrung, insbesondere für JavaScript-basierte Anwendungen.
- Puppeteer: Puppeteer ist eine Node-Bibliothek, die eine High-Level-API zur Steuerung von headless Chrome oder Chromium bietet. Es eignet sich hervorragend für das Scrapen und die Automatisierung von Browser-Aufgaben, erfordert jedoch im Vergleich zu Cypress möglicherweise mehr manuelle Konfiguration für End-to-End-Tests.
- Playwright: Playwright ist ein weiteres von Microsoft entwickeltes Cross-Browser-Automatisierungsframework. Es hat Ähnlichkeiten mit Puppeteer, bietet aber eine breitere Browser-Unterstützung. Cypress verfügt über einen einzigartigen Time-Traveling-Debugger und eine stärker integrierte Testumgebung.
Die Wahl des Frameworks hängt von den spezifischen Bedürfnissen und Anforderungen Ihres Projekts ab. Cypress ist eine ausgezeichnete Wahl für moderne Webanwendungen, die schnelles, zuverlässiges und entwicklerfreundliches End-to-End-Testing erfordern.
Praxisbeispiele für Cypress in Aktion
Lassen Sie uns einige Praxisbeispiele untersuchen, wie Cypress zum Testen verschiedener Arten von Webanwendungen verwendet werden kann:
Testen einer E-Commerce-Anwendung
Sie können Cypress verwenden, um verschiedene Benutzerabläufe in einer E-Commerce-Anwendung zu testen, wie zum Beispiel:
- Suchen nach Produkten
- Hinzufügen von Produkten zum Warenkorb
- Zur Kasse gehen und eine Bestellung aufgeben
- Verwalten von Kontoeinstellungen
Hier ist ein Beispiel für einen Cypress-Test, der überprüft, ob ein Benutzer erfolgreich ein Produkt in seinen Warenkorb legen kann:
it('Fügt ein Produkt zum Warenkorb hinzu', () => {
cy.visit('/products')
cy.get('.product-card').first().find('button').click()
cy.get('.cart-count').should('have.text', '1')
})
Testen einer Social-Media-Anwendung
Sie können Cypress verwenden, um Benutzerinteraktionen in einer Social-Media-Anwendung zu testen, wie zum Beispiel:
- Erstellen eines neuen Beitrags
- Liken eines Beitrags
- Kommentieren eines Beitrags
- Folgen anderer Benutzer
Hier ist ein Beispiel für einen Cypress-Test, der überprüft, ob ein Benutzer erfolgreich einen neuen Beitrag erstellen kann:
it('Erstellt einen neuen Beitrag', () => {
cy.visit('/profile')
cy.get('#new-post-textarea').type('Hallo, Welt!')
cy.get('#submit-post-button').click()
cy.get('.post').first().should('contain', 'Hallo, Welt!')
})
Testen einer Banking-Anwendung
Für Banking-Anwendungen kann Cypress verwendet werden, um kritische Funktionalitäten zu testen, wie zum Beispiel:
- Sicheres Einloggen
- Überprüfen von Kontoständen
- Überweisen von Geldern
- Verwalten von Begünstigten
Ein Test zur Überprüfung einer Geldüberweisung könnte so aussehen (mit entsprechendem Stubbing aus Sicherheitsgründen):
it('Überweist erfolgreich Geld', () => {
cy.visit('/transfer')
cy.get('#recipient-account').type('1234567890')
cy.get('#amount').type('100')
cy.intercept('POST', '/api/transfer', { statusCode: 200, body: { success: true } }).as('transfer')
cy.get('#transfer-button').click()
cy.wait('@transfer')
cy.get('.success-message').should('be.visible')
})
Fazit
Cypress ist ein leistungsstarkes und vielseitiges End-to-End-Testing-Framework, das Ihnen helfen kann, die Qualität und Zuverlässigkeit Ihrer Webanwendungen sicherzustellen. Seine entwicklerfreundliche API, leistungsstarke Funktionen und hervorragende Performance machen es zu einer beliebten Wahl bei Entwicklern und QA-Ingenieuren weltweit. Indem Sie die in diesem Leitfaden beschriebenen Best Practices befolgen, können Sie effektive Cypress-Tests schreiben, die Ihnen helfen, Fehler frühzeitig im Entwicklungsprozess zu erkennen und Ihren Benutzern qualitativ hochwertige Software zu liefern.
Da sich Webanwendungen ständig weiterentwickeln, wird die Bedeutung von End-to-End-Tests nur zunehmen. Die Einführung von Cypress und die Integration in Ihren Entwicklungsworkflow werden Sie befähigen, robustere, zuverlässigere und benutzerfreundlichere Weberfahrungen zu schaffen.