blog-cover

Testing-Framework Universum für JavaScript und Cypress

Von am 04.10.2023

Von React über Angular bis hin zu Vue.js – die Vielfalt an Frameworks ist schier endlos und wächst stetig. Mit dieser Fülle an Optionen kommen jedoch auch Herausforderungen, insbesondere wenn es um die Qualitätssicherung unserer Webanwendungen geht. In diesem Blogbeitrag tauchen wir in die Welt der Testing-Frameworks ein, beleuchten, warum zuverlässige Tests von entscheidender Bedeutung sind, und stellen einige bewährte Testing-Frameworks vor, die dabei helfen, die Stabilität und Performance der Projekte zu gewährleisten.

In diesem Artikel werden wir auch einen Schwerpunkt auf Cypress legen. Wir werden erläutern, warum Cypress eine gute Wahl ist und es mit anderen Frameworks vergleichen. Außerdem werden wir die Testkonzepte beleuchten, die mit Cypress umgesetzt werden können.


Übersicht über Testing Frameworks für JavaScript und Frontend

Bevor wir uns in die Details vertiefen, werfen wir einen Blick auf einige der gängigsten Testing Frameworks für JavaScript und Frontend-Entwicklung:

Jest
Jest ist ein weit verbreitetes JavaScript-Testing-Framework, das sich hervorragend für Unit-Tests eignet. Es wird oft in Kombination mit React-Anwendungen verwendet und bietet eine einfache Syntax und leistungsstarke Testfunktionen.

Unit-Tests (Komponententests)
Sind Tests, bei denen einzelne Komponenten oder Units eines Programms isoliert getestet werden. Diese Komponenten können Funktionen, Methoden oder Klassen sein. Das Hauptziel von Unit-Tests besteht darin, sicherzustellen, dass jede einzelne Komponente ordnungsgemäß funktioniert und die erwarteten Ergebnisse liefert, unabhängig von anderen Teilen des Codes.

Mocha
Mocha ist ein äußerst flexibles und anpassbares JavaScript-Testframework. Es unterstützt verschiedene Assertion-Libraries wie Chai und kann sowohl für Unit- als auch für Integrationstests verwendet werden.

Integrationstests
Sind eine Art von Softwaretests, bei denen mehrere Komponenten oder Module einer Anwendung zusammengeführt und als Einheit getestet werden, um sicherzustellen, dass sie reibungslos miteinander interagieren. Das Hauptziel von Integrationstests besteht darin, sicherzustellen, dass die verschiedenen Teile einer Anwendung korrekt zusammenarbeiten und die erwarteten Ergebnisse liefern, wenn sie zusammengefügt werden.

Jasmine
Jasmine ist ein Behavior-Driven Development (BDD)-Framework für JavaScript, das klare und leicht verständliche Syntax bietet. Es eignet sich hervorragend für BDD-orientierte Teams und Projekte.

Selenium
Selenium ist ein plattformübergreifendes Framework zur Browser-Automatisierung und wird oft für End-to-End-Tests eingesetzt. Es unterstützt verschiedene Programmiersprachen, darunter JavaScript, und ermöglicht das Testen in verschiedenen Browsern.

Cypress
Cypress ist ein End-to-End-Testing-Framework, das speziell für moderne Frontend-Entwicklung entwickelt wurde. Es bietet eine einfache Herangehensweise an das Testen von Webanwendungen.


Warum Cypress?

Cypress sticht aus mehreren Gründen unter den Testing Frameworks hervor und bietet eine Reihe überzeugender Vorteile.

Hauptargumente als Testing-Framework für JavaScript Frameworks

  • Ein All-in-One-Test-Framework, Assertion Library, mit Mocking und Stubbing
  • Schwerpunkt auf E2E- und Komponententests – Tests unter realen Bedingungen
  • Läuft im Browser und ist in JavaScript geschrieben
  • Nativer Zugriff auf das DOM und auf Ihre Anwendung

Einfache Installation und Benutzerfreundlichkeit
Die Installation von Cypress ist denkbar einfach. Es kann mit npm oder yarn installiert werden und ist in wenigen Minuten einsatzbereit sein. Cypress bietet eine intuitive API und eine klare Syntax, die auch für Entwickler ohne umfangreiche Testing-Erfahrung leicht verständlich ist.

Echtzeit-Reloading
Eine der herausragenden Eigenschaften von Cypress ist die Fähigkeit, Tests in Echtzeit zu beobachten, während sie ausgeführt werden. Entwickler können Tests schreiben und gleichzeitig die Anwendung entwickeln, da sie sofortiges Feedback über den Teststatus erhalten.

End-to-End-Testing
Cypress wurde speziell für End-to-End-Tests entwickelt und bietet native Unterstützung für verschiedene Browser. Dies ermöglicht es, die Anwendung unter realen Bedingungen zu testen und sicherzustellen, dass sie auf verschiedenen Plattformen einwandfrei funktioniert.

Mächtige Debugging-Tools
Cypress verfügt über leistungsstarke Debugging-Tools, darunter die Möglichkeit, Tests schrittweise auszuführen, Screenshots aufzunehmen und den Teststatus in Echtzeit zu überwachen. Dies erleichtert die Fehlerbehebung erheblich.

Community und Erweiterbarkeit
Cypress hat eine aktive Community, die eine Fülle von Plugins und Erweiterungen entwickelt hat. Dies ermöglicht es Entwickler:innen, Cypress an ihre speziellen Anforderungen anzupassen und von der Arbeit der Community zu profitieren.

Kontinuierliche Integration
Cypress lässt sich nahtlos in gängige CI/CD-Pipelines integrieren. Dadurch können automatisierte Tests in den Entwicklungsprozess integriert werden, um sicherzustellen, dass der Code immer fehlerfrei ist.

Zeitreise
Cypress macht Schnappschüsse, während die Tests laufen. Im Befehlsprotokoll sieht man, was bei jedem Schritt passiert ist.

Chai
Ist ein Assertions-Framework für JavaScript, das in Kombination mit Cypress verwendet werden kann. Es ermöglicht Entwickler:innen, Aussagen (Assertions) in ihren Tests zu formulieren, um zu überprüfen, ob bestimmte Bedingungen erfüllt sind. Diese Bedingungen können sein, dass eine Variable einen bestimmten Wert hat, eine Funktion ohne Fehler ausgeführt wird oder ein Element auf einer Webseite bestimmte Eigenschaften aufweist.

Fehlersuchbarkeit
Höre auf zu raten, warum die Tests fehlgeschlagen sind. Debugge direkt aus vertrauten Tools wie den Developer Tools. Die lesbaren Fehler- und Stack-Trace machen das Debugging blitzschnell.

Automatisches Warten
Fügen den Tests keine Wartezeiten oder Schlafphasen hinzu. Cypress wartet automatisch auf Befehle und Assertions, bevor es weitergeht.

Spione, Stubs
Überprüfe und kontrolliere das Verhalten von Funktionen, Serverantworten.

Screenshots, Videos und Testwiederholung
Zeige Screenshots an, die bei Fehlern automatisch erstellt werden, oder Videos, falls aktiviert, von der gesamten Testsuite, wenn diese über die CLI ausgeführt wird.

Browserübergreifende Tests
Führe Tests in Browsern der Firefox- und Chrome-Familie (einschließlich Edge und Electron) lokal und optimal in einer Pipeline für die kontinuierliche Integration aus.


Was kann Cypress nicht?

  • Cypress ist keine Universal-Testlösung. Dieses Framework ist speziell für eine Aufgabe konzipiert: End-to-End-Tests während des Entwicklungsprozesses für die Anwendung, nicht nach der Entwicklung.
  • Cypress ermöglicht keine Tests über mehrere Tabs oder gleichzeitig in verschiedenen Browsern durchzuführen. Die Tatsache, dass “Cypress innerhalb des Browsers ausgeführt wird”, bringt zusätzliche Begrenzungen mit sich. Das bedeutet, dass es nicht möglich ist, zu überprüfen, ob beim Klicken auf einen Link ein neuer Tab geöffnet wird.

Cypress im Vergleich zu anderen Frameworks

Um die Vorzüge von Cypress besser zu verstehen, werfen wir einen kurzen Blick auf die Unterschiede zu anderen Frameworks:

Jest
Jest ist hervorragend für Unit-Tests geeignet, während Cypress auf End-to-End-Tests spezialisiert ist. Cypress bietet eine umfassendere Lösung für die Gewährleistung der Funktionsfähigkeit einer Anwendung unter realen Bedingungen.

Mocha
Mocha ist äußerst flexibel, aber es fehlen einige der integrierten Funktionen von Cypress, wie das Echtzeit-Reloading und die automatische Wiedergabe von Tests.

Jasmine
Jasmine ist ein BDD-Framework und legt den Fokus auf die Spezifikation des Verhaltens der Anwendung. Cypress bietet ähnliche Funktionen, aber mit einem stärkeren Fokus auf End-to-End-Tests.

Selenium WebDriver
Während Cypress im Browser ausgeführt werden kann, interagiert WebDriver mit dem Browser über das HTTP-Protokoll, was zu Verzögerungen und unbekannten Warteereignissen bei der Ausführung von Tests. Cypress richtet sich auch an QA- und Entwickler-Teams, die Tests schreiben wollen, ohne sich um die zugrunde liegende Infrastruktur und die Beschränkung auf eine Assertion-Bibliothek und einer Programmiersprache.


Cypress Grundlagen

describe-Block
Die Tests werden in einem describe-Block abgelegt. Dieser Block enthält zwei Argumente. Das erste ist eine Beschreibung dessen, was getestet werden soll. Das zweite ist eine Callback-Funktion für den eigentlichen Tests innerhalb dieses Blocks.

it-Block
Innerhalb des Beschreibungsblocks gibt es auch it-Blöck. Diese Blöcke sind einzelne Tests innerhalb einer Gesamttestdatei. Die API für it() ist die gleiche wie die von describe. Das erste Argument ist der Titel eines einzelnen Tests, und das zweite Argument ist eine Callback-Funktion, die den Testcode enthält.

Befehle und Interaktion mit Elementen
Cypress stellt verschiedene Befehle zur Verfügung, die beim Testen unterstützen. Man kann diese Befehle auf das cy-Objekt anwenden. Zum Beispiel führt cy.visit('/') den Cypress Runner zu einer gewünschten Seite. Es gibt verschiedene andere Befehle wie cy.click(), cy.type(), cy.check(), usw.

Elemente erhalten
Sehr oft gibt es den Fall, wo man ein Element aus dem DOM erhalten möchte und dazu eine eine Art von Behauptung aufstellen möchte. Zum Beispiel soll ein h1-Element einen bestimmten Text beinhalten. Man kann Elemente in Cypress mit der Funktion get abrufen und auch einen CSS-Abfrage-Selektor übergeben.

Command Chaining & Assertions
Nachdem man ein Element erhalten haben, möchten man wahrscheinlich etwas mit diesem Element tun, z. B. eine Behauptung aufstellen. Dies kann umgesetzt werden, indem man eine Behauptung anhängen, nachdem man ein Element erhalten hat. Zum Beispiel: get(h1).contains('text'). Cypress hat verschiedene Möglichkeiten, eine Behauptung aufzustellen.

Fokussierung auf einen einzigen Test
Man kann it.only() verwenden, um einen einzelnen Test durchzuführen.

beforeEach
Man kann eine beforeEach-Funktion verwenden, um bestimmte Aktionen vor jedem Test durchzuführen.


Testkonzepte mit Cypress

Mit Cypress können verschiedene Testkonzepte in der Frontend-Entwicklung umgesetzt werden:

End-to-End
Cypress wurde ursprünglich für die Durchführung von End-to-End-Tests (E2E) für alle Anwendungen entwickelt, die in einem Browser laufen. Ein typischer E2E-Test besucht die Anwendung in einem Browser und führt Aktionen über die Benutzeroberfläche aus, wie es ein echter Benutzer tun würde.

Komponente
Man kann Cypress auch verwenden, um Komponenten aus unterstützten Web-Frameworks einzubinden und Komponententests durchzuführen.

API
API Cypress kann beliebige HTTP-Aufrufe ausführen, so dass Sie es für API-Tests verwenden können.


Best Practices laut cypress.io

Teste „Unhappy Paths“
Teste nicht nur den “Happy Path“ des Nutzers. Stelle sicher, dass man Nutzer testet, die die App böswillig nutzen oder Aktionen durchführen, die nicht üblich sind.

Stabile Selektoren verwenden
Verwende data-*-Attribute, um Ihren Selektoren einen Kontext zu geben und sie von CSS- oder JS-Änderungen zu isolieren. Ziele nicht auf Elemente ab, die auf CSS-Attributen wie id, class, tag basieren. Ziele nicht auf Elemente, die ihren textContent ändern können. Verwende keine zu generischen Selektor (z. B. cy.get(button)).

Keine Rückgabewerte zuweisen
Cypress läuft NICHT synchron zueinander.

Teste keine externen Seiten oder Plugins
Teste nur Websites oder Plugins, die du direkt kontrollierst. Versuche zu vermeiden, einen Server eines Drittanbieters zu verwenden. Eine Möglichkeit wäre ein API-Call von Cypress mittels cy.request(), um mit Servern von Drittanbietern über deren APIs zu kommunizieren.

Halte Tests untereinander unabhängig
Machen einen Test nicht von einem anderen abhängig, dies könnte das Testverhalten und die Logik dahinter nur unnötig beeinflussen.

Bereinige den Zustand vor der Ausführung der Tests
Bereinige den Zustand nicht mit after oder afterEach. Ein Vorteil von Cypress ist das inkrementelle Schreiben von Tests und Anwendungscode. Wenn der Zustand nach einem Test nicht aufrechterhalten wird, kann es schwieriger werden, herauszufinden, was als nächstes getestet werden soll. Wenn mitten im Test etwas fehlschlägt, haben die Nachbereinigungsfunktionen keine Chance, ausgeführt zu werden. Cypress bereinigt den Zustand zwischen den Tests bereits, so dass man sich darüber keine Gedanken machen muss.

Fazit

Obwohl es viele gute Alternativen gibt, sticht Cypress hervor, insbesondere wenn es um End-to-End-Tests geht. Mit seiner einfachen Installation, Echtzeit-Reloading, mächtigen Debugging-Tools und der starken Community bietet Cypress alles, was Entwickler- und QA-Teams für zuverlässige Tests benötigen. Wenn man nach einem effektiven und benutzerfreundlichen Testing Framework für JavaScript und Frontend-Entwicklung sucht, ist Cypress zweifellos ein guter Start.

Da ich im Laufe der Masterklasse ein mögliche Spezialisierung Richtung (Software) Testing anstrebe, versuche ich so viel Know-now diesbezüglich zu sammeln. Dafür hab ich eine kleine Sammlung an nützlichen Links zusammengestellt, diese wird in Zukunft auch weiter ergänzt.

Außerdem werden die ersten Testings-Workflows für ein Ionic-Webprojekt im Rahmen der Mastklasse in Cypress erstellt.


Quellen

The comments are closed.