Webanwendungen mit Cypress und
Cucumber testen

Schritt-für-Schritt Anleitung

End-to-End-Tests sind ein wichtiger Teil der Softwareentwicklung. Sie gehen noch einen Schritt weiter als Integrationstest und simulieren den tatsächlichen späteren Einsatz des Systems. Hat das Softwareprodukt eine Weboberfläche, wird häufig eine Benutzereingabe simuliert und eine entsprechende Reaktion erwartet. Wer solche End-to-End-Tests für Webanwendungen schreiben will, stößt unweigerlich auf Cypress, da es neben Selenium eines der bekanntesten Frameworks zum Testen von Webanwendungen ist.

Cypress-Tests bestehen aus mehreren aufeinanderfolgenden Schritten. Da in den Tests häufig die gleichen Aktionen ausgeführt werden, enthalten die Tests viele Duplikate. 

Hier kommt Cucumber ins Spiel: Es sorgt dafür, dass diese sich häufig wiederholenden Teile wiederverwendet werden können. Zudem kann Cucumber häufig verhindern, dass die Tests jedes Mal von Entwicklern manuell angepasst oder erweitert werden müssen, wenn Änderungen in der Webanwendung gemacht oder neue Funktionen entwickelt werden. Cucumber befähigt Tester, diese kleineren Anpassungen in überschaubarer Zeit selbst zu erledigen. Zu Beginn müssen die Entwickler noch viele sogenannte step definitions in Cypress neu implementieren, später kann der Tester diese selbstständig wiederverwenden und viel Entwicklungszeit sparen. 

Welche weiteren Vor- und Nachteile Cucumber in Verbindung mit Cypress hat und wie es aufgesetzt wird, wird in diesem Artikel genauer geschrieben. 

Grundfunktion

Wie in der Einleitung beschrieben, schreiben Testmanager sogenannte Szenarien, die in der
sehr einfach verständlichen Sprache Gherkin ein Testszenario beschreiben, das getestet
werden soll. Ein Beispiel:

WENN ich mich als “Theo Tester” anmelde 

DANN sehe ich die Startseite 

* wird mein Nutzername angezeigt 

Hinweis: “*” bedeutet in diesem Fall “UND DANN”. Bei längeren Szenarien verbessert diese
Schreibweise die Lesbarkeit.

Diese Testszenarien werden beispielsweise in Jira definiert und verwaltet. Sie werden von
einem Entwickler in step definitions implementiert und können von Testmanagern in
beliebiger Kombination und Reihenfolge wiederverwendet werden. Daraus ergibt sich zu
Beginn ein hoher Aufwand für den Entwickler und den Testmanager. Später jedoch, wenn
bereits viele step definitions implementiert wurden, hat der Entwickler, je nach Integration
von Cypress, wenig bis gar keinen Aufwand mehr

Vorteile

Die Vorteile liegen auf der Hand: Zum Ersten ist gut dokumentiert und für jeden einsehbar,
welche Testfälle es gibt und welche Funktionen noch unzureichend getestet sind. Zum
Zweiten wird die nötige Kommunikation zwischen Tester und Entwickler minimiert, da die
einzelnen Testfälle sehr ausdrucksstark und leicht zu verstehen sind. Und zum Dritten wird
der Entwicklungsaufwand zunehmend weniger.
Dieses Setup ermöglicht außerdem den automatischen Import neuer Szenarien in der
Buildpipeline und einen Export der entsprechenden Ergebnisse. Auf diese Funktionen wird
fortlaufend nicht weiter eingegangen.

Setup

In diesem Artikel wird das Setup in einem Angular-Projekt beschrieben. Im ersten Schritt
müssen die benötigten Abhängigkeiten installiert werden:

npm install – –savedev cypress @badeball/cypress-cucumber-preprocessor @cypress/webpack-preprocessor 

Um Cypress zu konfigurieren, wird die Datei cypress.config.js benötigt. Sie muss auf
der Root-Ebene neben beispielsweise der package.json angelegt werden. Der Inhalt
sollte in etwa so aussehen:

const {defineConfig} = require(“cypress”); 

const webpack = require(“@cypress/webpack-preprocessor”); 

const preprocessor = require(“@badeball/cypress-cucumber-preprocessor”); 

 

async function setupNodeEvents(on, config) { 

 await preprocessor.addCucumberPreprocessorPlugin(on, config); 

 

 on( 

   “file:preprocessor”, 

   webpack({ 

     webpackOptions: { 

       resolve: { 

         extensions: [“.ts”, “.js”], 

       }, 

       module: { 

         rules: [ 

           { 

             test: /\.feature$/, 

             use: [ 

               { 

                 loader: “@badeball/cypress-cucumber-preprocessor/webpack”, 

                 options: config, 

               }, 

             ], 

           }, 

         ], 

       }, 

     }, 

   }) 

 ); 

 return config; 

} 

 

module.exports = defineConfig({ 

 e2e: { 

   specPattern: “**/*.feature”, 

   supportFile: false, 

   video: false, 

   defaultCommandTimeout: 10000, 

   requestTimeout: 10000, 

   retries: { 

     runMode: 2, // 3 runs in total 

   }, 

   setupNodeEvents, 

 }, 

}); 

Der untere Abschnitt kann nach Bedarf angepasst werden. Alle Konfigurationsparameter
können Sie hier nachlesen.
In der package.json muss folgende Konfiguration ergänzt werden:

{ 

  … 

  “devDependencies”: { 

  … 

  }, 

  “cypress-cucumber-preprocessor”: { 

    “stepDefinitions”: [ 

      “cypress/e2e/step_definitions/*.cy.js” 

    ] 

  } 

} 

Nun kann die erste .feature-Datei
{Projektverzeichnis}/cypress/e2e/{Feature}/testcase.cy.feature und
die step definitions
{Projektverzeichnis}/cypress/e2e/step_definitions/steps.cy.js
hinzugefügt werden. Die testcase.cy.feature-Datei könnte beispielsweise so
aussehen:

#language: de 

Funktionalität: Default 

  Szenario: Korrekte Seite wird geladen 

    Wenn ich die cypress website aufrufe 

    Dann enthält die Überschrift “Kitchen Sink”

 

Während die Datei steps.cy.js  folgendes enthält:

import {Then, When} from “@badeball/cypress-cucumber-preprocessor”; 

 

When(‘ich die cypress website aufrufe’, () => { 

 cy.visit(‘https://example.cypress.io’); 

}); 

 

Then(‘enthält die Überschrift {string}’, headline => { 

 cy.get(‘h1’).should(‘contain.text’, headline) 

}); 

Nun muss das Frontend lokal gestartet und Cypress mit folgendem Kommando aufgerufen
werden:

npx cypress open 

In dem sich öffnenden Fenster muss “E2E Testing” und anschließend ein Browser
ausgewählt werden, in dem der Test ausgeführt werden soll. Wenn alles richtig konfiguriert
ist, wird im nächsten Fenster die .feature.-Datei angezeigt und mit einem Klick darauf der
Test ausgeführt.
Ein vollständig konfiguriertes Angular-Projekt ist hier hinterlegt.

Integration in CI/CD

Cypress bietet umfangreiche Integration in gängige CI/CD-Tools. In diesem Artikel wird die Integration in Github Actions beleuchtet. Cypress stellt für das automatisierte Ausführen der Tests die offizielle Github Action “cypress-io/github-action” zur Verfügung. Alle Konfigurationsparameter sind hier dokumentiert. Eine einfache Grundkonfiguration könnte beispielsweise so aussehen:

jobs: 

 e2e: 

   name: Cypress Tests 

   runs-on: ubuntu-22.04 

   steps: 

     – name: Checkout 

       uses: actions/checkout@v3 

 

     – name: Setup node 

       uses: actions/setup-node@v3 

       with: 

         node-version: 18 

 

     – name: Install Dependencies 

       run: npm install 

 

     – name: Cypress run 

       uses: cypress-io/github-action@v5 

       with: 

         browser: chrome 

         record: false 

         wait-on: ‘http://127.0.0.1:4201’ 

         install-command: npm install -g @angular/cli@14 

       env: 

         TZ: Europe/Berlin 

 

     – name: Save screenshots folder 

       uses: actions/upload-artifact@v3 

       if: failure() 

       with: 

         name: cypress-screenshots 

         path: cypress/screenshots 

         retention-days: 5 

 
 
 

Nachteile

Es kann je nach Funktionsumfang und Alter des Frontends dazu kommen, dass für die
eigentlich gleiche Funktion mehrere leicht unterschiedliche Implementierungen zum Einsatz
kommen. Beispielsweise kann ein Button mehrere mit Bedingungen versehene
<div>-Elemente enthalten oder eben nicht. Um solche Differenzen zu berücksichtigen,
ohne die Testcases aus technischen Gründen unterschiedlich zu formulieren, müssen die
einzelnen step definitions entsprechend flexibel gestaltet werden, um mit unterschiedlichen
Implementierungen zurechtzukommen. Das erhöht den Entwicklungsaufwand und kann zu
unerwarteten Problemen beim erstmaligen Ausführen neuer Testfälle führen.

Fazit

Cucumber und Cypress arbeiten sehr gut zusammen. Der anfangs investierte Aufwand
rentiert sich vergleichsweise früh und führt zu besserer Testdokumentation, effizienterer
Kommunikation zwischen Tester und Entwickler sowie schnellerer Erweiterung der Testfälle.
Nachteilig ist die, ab einem gewissen Testumfang nötige, flexible Gestaltung der step
definitions
zu nennen.

Neugierig geworden?

Wir unterstützen Sie gerne dabei. Sprechen Sie uns einfach an.

Kontakt

Tom Schindler
Telefon: +49 (0)40 53302-0
E-Mail: Tom.Schindler@cimt-ag.de

cimtAcademy

Jetzt registrieren und keine Veranstaltungen mehr verpassen.​



    Nach oben scrollen