Automatisierte End-To-End Tests mit Cypress

Automatisiertes Testen oder Testautomatisierung ist eine Technik für Softwaretests, bei der spezielle Softwaretools für automatisiertes Testen verwendet werden, um eine Test-Suite auszuführen. Im Gegensatz dazu wird das manuelle Testen von einem Menschen durchgeführt, der vor einem Computer sitzt und sorgfältig einzelne Testschritte ausführt. Die Software für automatisiertes Testen kann auch Testdaten in das zu testende System eingeben, erwartete und tatsächliche Ergebnisse vergleichen und detaillierte Testberichte erstellen. Testautomatisierung ist also der beste Weg, um die Effektivität, Testabdeckung und Ausführungsgeschwindigkeit beim Softwaretest zu erhöhen. Automatisierte Softwaretests sind aus folgenden Gründen wichtig:

  • Manuelles Testen aller Workflows, aller Felder, aller negativen Szenarien ist zeit- und kostenintensiv.
  • Es ist schwierig, mehrsprachige Seiten manuell zu testen.
  • Testautomatisierung im Softwaretest erfordert kein menschliches Eingreifen. Man kann die automatisierten Tests unbeaufsichtigt (über Nacht) durchführen.
  • Testautomatisierung erhöht die Geschwindigkeit der Testausführung.
  • Automatisierung hilft, die Testabdeckung zu erhöhen.
  • Manuelles Testen kann eintönig und damit fehleranfällig werden.

End-To-End Tests

End-to-End-Tests sind eine Technik, die das gesamte Softwareprodukt von Anfang bis Ende testet, um sicherzustellen, dass sich der Anwendungsablauf wie erwartet verhält. Es definiert die Systemabhängigkeiten des Produkts und stellt sicher, dass alle integrierten Teile wie erwartet zusammenarbeiten.

Der Hauptzweck von End-to-End-Tests (E2E-Tests) besteht darin, aus der Sicht des Endanwenders zu testen, indem das reale Anwenderszenario simuliert und das zu testende System und seine Komponenten auf Integration und Datenintegrität überprüft werden.

Heutzutage sind Softwaresysteme komplex und mit zahlreichen Subsystemen verbunden. Wenn eines der Subsysteme ausfällt, kann das gesamte Softwaresystem abstürzen. Dies ist ein großes Risiko und kann durch End-to-End-Tests verringert werden.

Cypress ist ein Frontend-Testwerkzeug für End-To-End Testing, das für das moderne Web entwickelt wurde. Cypress besteht aus einem freien, quelloffenen, lokal installierten Test Runner und einem Dashboard Service zur Aufzeichnung unserer Tests. Cypress hilft uns, Tests einzurichten und täglich zu schreiben, während wir unsere Anwendung lokal bauen. Nach dem Aufbau einer Testsuite und der Integration von Cypress in einen CI-Provider kann der Dashboard Service unsere Testläufe aufzeichnen. Wir werden uns nie mehr den Kopf darüber zerbrechen müssen, warum etwas fehlgeschlagen ist.

Cypress hat auch ein einfacheres Onboarding als andere Frameworks.  Mit npm kann man Cypress einfach mit einem einzigen Befehl installieren. Man erhält alle Screenshots und Videos standardmäßig auf jedem CI-Server, auf jeder Plattform. 

Lass uns mit den Beispielen beginnen!

Die Installation von Cypress erfolgt über den Befehl „npm install cypress“. Die Anwendung bekommt man zum Laufen mit „npx cypress open“. Nachdem man zum ersten Mal den „npx cypress open“ Befehl ausführt, wird ein Projekt mit folgender Struktur erzeugt:

Fixtures sind eine gute Möglichkeit, Daten für Antworten auf Routen zu spiegeln. Es gibt ein paar vordefinierte Beispiele im Ordner integration/examples. Ich werde sie alle löschen, und wir werden unsere eigenen Beispiele erstellen.

Damit man versteht, wie Cypress funktioniert, fange ich gleich mit einem Beispiel an.
Wenn wir z. B. die Blogpost-Seite mit dem Thema “Microframeworks mit Kotlin” öffnen, stellen wir fest, dass der URL-Link das Wort “Microframeworks” enthält. Durch Drücken von F12 können wir eine Inspektion der Seite vornehmen.

Das obige Bild zeigt uns, dass der Titel ein “h1”-Element ist. Wenn wir z. B. nach “h6”-Elementen suchen, werden wir keine finden.

Schauen wir uns an, wie ein Test mit Cypress aussieht:

describe('Browser Actions', () => {
    it.only('should load correct url', () => {
        cy.visit('https://blog.oio.de/2021/01/22/microframeworks-mit-kotlin/',
        {timeout:10000 }) 
    })

    it.only('should check correct url', () => {
       cy.url().should('include', 'microframeworks')  
    })

    it.only('should check for current element on the page', () => {
        cy.get('h1').should('be.visible')
     })

     it.only('should wait for 3 seconds', () => {
        cy.wait(3000)
     })

     it.only('should check for current element on the page', () => {
        cy.get('h6').should('be.visible')
     })

})

Wir haben nun alle oben beschriebenen Fälle in einem “describe”-Block zusammengefasst. Mit dem Befehl cy.visit(…) wird eine bestimmte URL angesteuert. Der Timeout ist optional: wenn sich die Seite nicht innerhalb der angegebenen Zeit öffnet, erhält man eine Timeout-Fehlermeldung. Mit cy.url().should('include', 'microframeworks') erfolgt die Abfrage, ob das Schlüsselwort (in unserem Fall “microframeworks”) in der angegebenen URL enthalten ist und mit cy.wait(...) wartet man ein wenig, bis man den nächsten Block ausführt. Die Zeit ist dann in ms angegeben.

Nach dem Ausführen des Befehls npx cypress open erscheint ein Pop-up-Fenster, das folgendermaßen aufgebaut ist.

Da ich die Standardbeispiele gelöscht habe, ist nur noch ein Beispiel sichtbar, unser oben erstelltes Beispiel. Alle Tests sollten korrekt laufen, bis auf den mit dem Element ‘h6’. Glaubt ihr, dass es passt? Schauen wir uns die Antwort an.

Ja, wir haben es geschafft. Das Schönste an Cypress ist die detaillierte Beschreibung, wenn ein Test durchläuft oder fehlschlägt.

So, jetzt haben wir die Einführung hinter uns gebracht, sehen wir uns einige API-Tests an.
Schauen wir uns die vorherige Beispielseite noch einmal an und betrachten wir die Netzwerkanalyse der Header.

Ich habe auch die Informationen hervorgehoben, die wir für unsere nächsten Tests benötigen.

Wir prüfen nun, ob der Header der Anfrage vom Typ text/html; charset=UTF-8 ist und ob der Status 200 ist, also ob der Request erfolgreich durchgeführt wurde. Das Schlüsselwort in diesem Fall ist cy.request(...), das die Antwort als Objektliteral liefert, das Eigenschaften wie status, body, headers und duration enthält.

describe('REST API Test with Cypress', () => {
  it.only('API TEST - Validate Header', () => {
    cy.visit('https://blog.oio.de/2021/01/22/microframeworks-mit-kotlin/')
    cy.request('https://blog.oio.de/2021/01/22/microframeworks-mit-kotlin/').as('microframeworks')
    cy.get('@microframeworks') //alias
      .its('headers')
      .its('content-type')
      .should('include', 'text/html; charset=UTF-8')
  })

  it.only('API TEST - Validate Status Code', () => {
    cy.request('https://blog.oio.de/2021/01/22/microframeworks-mit-kotlin/').as('microframeworks')
    cy.get('@microframeworks').its('status').should('equal', 200)
  })

})

Was passiert aber, wenn wir eine nicht existierende Seite aufrufen wie z.B. “https://blog.oio.de/2021/01/22/microframeworks-mit-kotlinnnnnnnnn“? Wir erhalten dann eine Antwort mit dem Status 404. 404 ist ein Statuscode, der angibt, dass eine angeforderte Seite nicht gefunden wurde. 404 und andere Statuscodes wie 200 sind Teil des Hypertext Transfer Protocol des Webs.

Wenn wir uns die Kopfzeilen der Netzwerkanalyse mit F12 ansehen, erkennen wir Folgendes:

Nun führen wir einen weiteren Test durch, um zu sehen, ob dies zutrifft. Wir rufen die Methode cy.request(…) auf, die einen GET auf die URL ausführt.

 it.only('API TEST - Validate Negative Status Code', () => {
    cy.request({
      method: 'GET',
      url: 'https://blog.oio.de/2021/01/22/microframeworks-mit-kotlinnnnnnnnn/',
      failOnStatusCode: false,
    }).as('microframeworks')
    cy.get('@microframeworks').its('status').should('equal', 404)
  })

Das Ergebnis für die 3 Tests ist nachstehend zu sehen

Wir stellen fest, dass die Antworten so sind, wie wir es auch erwartet haben. Das sollte es mit den Demo-Beispielen gewesen sein. Jetzt ist es der Zeitpunkt, die Diskussion um die Vor- und Nachteile fortzusetzen.

Vorteile und Nachteile

Cypress wurde für Entwickler und QA-Ingenieure mit der Absicht entwickelt, das Testen der Benutzeroberfläche zu vereinfachen. Es kann alles testen, was in einem Browser läuft.  Mit Cypress muss man die Tests mit JavaScript schreiben. Wenn man ein Front-End-Entwickler ist oder JavaScript kennt, ist das sehr gut!  Man kann Tests in der gleichen Sprache wie den Code schreiben. Aber leider unterstützt Cypress keine andere Sprache.  Mit Selenium z.B. kann man die Tests in vielen unterstützten Sprachen schreiben. Wenn man bereits Back-End-Operationen mit einer anderen Sprache durchführt, macht es möglicherweise keinen Sinn, Cypress zu verwenden.  Es erfordert auch mehr fortgeschrittene Javascript-Kenntnisse (Promises, JQuery) als Webdriver-NodeJS-Frameworks.  Zum Beispiel gibt es keine async/await-Unterstützung.  Da es im Browser läuft, gibt es keine Unterstützung für mehrere Tabs.

Bis zum Frühling 2020 unterstützte Cypress nur Chrome.  Mit einer neuen Version hat Cypress jedoch begonnen, auch Firefox und Edge zu unterstützen.  Jetzt können Unternehmen mit Cypress auch Cross-Browser-Tests durchführen.  Chrome ist der beliebteste Browser, sodass Cypress +70% des Marktes zwischen Chrome, Firefox und Edge abdeckt. Trotzdem unterstützt Cypress keine anderen Browser wie IE, Safari oder Opera. Wenn man sicherstellen muss, dass die Webanwendungen in allen Browsern reibungslos laufen, ist Cypress möglicherweise keine gute Option.

Wenn es um Stabilität geht, hat Cypress einen eingebauten Mechanismus, der das Warten auf DOM-Elemente handhabt (es gibt eine Einstellung für die maximale Wartezeit, die standardmäßig auf 10.000 ms eingestellt ist). Das bedeutet, dass Funktionen wie sleep oder wait nicht notwendig sind.  Außerdem werden dadurch einige Selenium-Webdriver-Fehler/Ausnahmen eliminiert, die durch dynamische Seiteninhalte verursacht werden.  Das Ergebnis sind stabilere Tests, die schneller laufen.  Es gibt auch eingebaute Wiederholungsversuche. Moderne Webanwendungen aktualisieren sich ständig selbst und sind ein wenig unberechenbar.  Das alles macht Cypress weniger unzuverlässig.

Wenn ihr Cypress cool findet und mehr darüber erfahren wollt, könnt ihr hier mehr Informationen finden.

Ich hoffe, dass es Spaß gemacht hat, zusammen Cypress zu testen. Bis zum nächsten Mal!

Views All Time
201
Views Today
4
Short URL for this post: https://blog.oio.de/lptHM
This entry was posted in Web as a Platform and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *