So testen Sie Ihre Web-Apps
In der Softwarebranche testet jeder seine Anwendungen auf irgendeine Weise. Viele Entwicklerteams haben ausgefeilte Testschemata, die gut in ihre Continuous Integration Pipelines integriert sind, aber selbst diejenigen, die keine automatischen Tests haben, müssen noch Wege finden, um zu überprüfen, ob ihr Code wie beabsichtigt funktioniert.
Das Erstellen einer Website und das manuelle Durchklicken mit Hilfe eines Browsers ist eine Vielzahl von Tests. Obwohl es nicht das anspruchsvollste ist, zählt es immer noch. Gleiches gilt für das Starten von cURL in der Konsole und das Senden einer synthetischen Anforderung an den soeben erstellten API-Endpunkt.
In diesem Beitrag wird erläutert, wie die manuellen Tests, die wir bereits durchführen, automatisiert werden können, bevor wir uns mit verschiedenen Testtypen und -methoden befassen.
Tests automatisieren
Manuelle Tests sind für kleine Apps ausreichend, aber wenn diese Apps wachsen, wächst ihre testbare Oberfläche mit ihnen, was zwei Probleme verursacht.
Erstens können Inkonsistenzen auftreten, wenn Benutzer jedes Mal Tests durchführen müssen, wenn eine neue Version einer App fertig ist. Dies gilt insbesondere, wenn es viele Tests gibt. Zweitens kann die Person, die die Tests durchführt, keine anderen Aufgaben ausführen. Bei großen Apps kann das Testen mehrere Tage dauern.
Der logischste Weg, diese beiden Probleme zu lösen, besteht darin, diese manuellen Aufgaben zu automatisieren. Für Web-Apps gibt es zwei Haupttypen von Tests: UI-Tests und API-Tests. Zwei Tools können sie automatisieren.
UI-Tests
UI-Tests können mit einem Tool namens Puppeteer durchgeführt werden. Mit Puppeteer können Sie einen manuellen UI-Test mit JavaScript automatisieren. Es wird über NPM mit dem folgenden Befehl installiert:
$ npm i puppeteer
Sie können dann ein Skript schreiben, das eine kopflose Version von Chrome steuert, um Ihre Tests auszuführen. Dieses Skript könnte wie folgt aussehen:
(async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://google.com', {waitUntil: 'networkidle2'}); const heading = await page.$('h1'); await browser.close(); if(!heading) console.log('No heading found!');})();
In diesem Skript starten wir eine kopflose Instanz von Chrome und navigieren zu example.com , und auf der Suche nach einem h1-Element. Wenn es nicht existiert, wird eine Fehlermeldung protokolliert.
API-Tests
API-Tests können über Postman automatisiert werden. Postman verfügt über eine grafische Oberfläche zum Erstellen von HTTP-Anforderungen, die gespeichert werden können. Diese Anfragen können später mit nur einem Mausklick ausgeführt werden.
Laden Sie zunächst die Postman-Benutzeroberfläche herunter und installieren Sie sie. Die folgenden Schritte sind erforderlich, um eine Anforderung zu erstellen und zu speichern:
- Klicken Sie links auf Sammlung erstellen
- Geben Sie Meine Sammlung als Sammlungsnamen ein
- Klicken Sie auf Erstellen
- Klicken Sie links auf die Auslassungspunkte (…) Meiner Sammlung
- Wählen Sie Anfrage hinzufügen
- Geben Sie Meine Anfrage als Anforderungsnamen ein
- Klicken Sie auf In meiner Sammlung speichern
Die Anfrage wird in der linken Seitenleiste unter Ihrer neu erstellten Sammlung angezeigt.
Wenn Sie es auswählen, müssen Sie Folgendes eingeben example.com als URL und fügen Sie einen Test. Um einen Test hinzuzufügen, klicken Sie in der Registerkartenleiste unter dem URL-Eingabefeld auf Tests.
Ein Textbereich, in den Sie Ihren Test in JavaScript schreiben können, wird angezeigt. Das Folgende ist ein Beispiel für einen Test:
pm.test("Status code is 200", () => { pm.response.to.have.status(200);});
Wenn Sie oben rechts auf dem Bildschirm auf Speichern klicken und direkt danach senden, wird Ihre Anfrage gesendet. Das Testskript wird dann ausgeführt, um festzustellen, ob die Antwort den Status 200 hatte oder nicht.
Arten von Tests
Es gibt drei verschiedene Arten von Tests. Wenn Sie sie verstehen, können Sie die richtige Art von Tests für die verschiedenen Teile Ihres Software-Stacks auswählen.
Unit-Tests
Unit-Tests sind die einfachste Art von Test. Sie überprüfen die Richtigkeit kleiner Teile Ihres Codes. Ein Komponententest umfasst normalerweise einen Aufruf einer Funktion oder eine Möglichkeit, eine Klasse zu verwenden.
Ein Komponententest ist normalerweise der erste “Benutzer” Ihres Codes. Bei einigen Testmethoden müssen Sie den Test sogar vor der Implementierung des eigentlichen Anwendungscodes schreiben.
Unit-Tests können sowohl in der Backend- als auch in der Frontend-Entwicklung verwendet werden. Einige Entwicklungsteams verwenden Komponententests, um die gerenderte DOM-Ausgabe kleiner Teile ihres Codes wie Formulare oder Menüs zu überprüfen. Im Backend werden häufig Unit-Tests verwendet, um den Code zwischen dem HTTP-Server und der Datenbank oder anderen APIs zu testen.
Drei weit verbreitete Testläufer für Komponententests sind:
‐ Jest—Jest wird hauptsächlich in der Frontend-Entwicklung verwendet, da es einzigartige Funktionen wie Snapshot-Tests bietet, die bei Problemen wie UI-Regressionen helfen. Ein Jest-Tutorial finden Sie hier.
– AVA-AVA wird in der Backend-Entwicklung bevorzugt, da es sich auf die hochparallele Ausführung von Tests spezialisiert hat. Ein AVA Tutorial finden Sie hier.
– PHPUnit-PHPUnit ist ein beliebtes Framework für Komponententests in PHP. Ein PHPUnit-Tutorial finden Sie hier .
Wenn für einen Komponententest externe Ressourcen wie Netzwerkverbindungen oder Datenbanken erforderlich sind, schreiben Sie wahrscheinlich einen Integrationstest. Diese Art von Test wird als nächstes behandelt.
Integrationstests
Aus Implementierungsperspektive sehen Integrationstests wie Komponententests aus. Der Unterschied besteht darin, dass Integrationstests mehrere Teile des Stapels zusammen testen. Sie können beispielsweise testen, ob Client und Server dasselbe Protokoll sprechen oder ob die Dienste in einer Microservices-Architektur ordnungsgemäß zusammenarbeiten.
Prüfungen, die normalerweise in mehreren unabhängigen Komponententests enden würden, können zu einem Integrationstest zusammengefasst werden, der feststellt, ob alles gut zusammenarbeitet.
Integrationstests werden sowohl in der Frontend- als auch in der Backend-Entwicklung eingesetzt. Sie werden manchmal verwendet, um festzustellen, ob die beiden Teile korrekt interagieren, aber sie können auch verwendet werden, um festzustellen, ob verschiedene Module eines Teils wie vorgesehen zusammenarbeiten.
Sie können dieselben Testläufer für Integrationstests verwenden, die Sie für Komponententests verwendet haben. Postman, das UI-Tool, das oben zur Automatisierung manueller API-Tests verwendet wurde, enthält jedoch auch ein CLI-Tool namens Newman, das in Ihre CI / CD-Pipeline integriert werden kann.
Newman kann exportierte Postman-Sammlungen ausführen, sodass Sie Anforderungen und Tests mit der Postman-Benutzeroberfläche erstellen und später über die CLI ausführen können. Ein Newman-Tutorial finden Sie hier.
Wenn ein Integrationstest eine Interaktion mit der Benutzeroberfläche erfordert, spricht man von einem UI—Test – adressiert als nächstes.
UI-Tests
UI-Tests sind die anspruchsvollsten Tests. Sie versuchen, das Benutzerverhalten automatisiert zu emulieren, damit Tester nicht jeden Teil ihrer App manuell durchklicken müssen.
UI-Tests helfen oft, eine bestimmte Interaktion zu erfassen, die zu einem Fehler für einen Benutzer geführt hat. Sobald es erfasst ist, kann es mit einem Klick reproduziert werden, um den Fehler zu beheben und zu verhindern, dass es in einer neuen Version zurückkommt.
Die zuvor erwähnten Jest- und AVA-Testläufer können hier verwendet werden, aber Sie benötigen normalerweise eine zusätzliche Bibliothek, um die Interaktion mit der Benutzeroberfläche über einen Browser zu erleichtern. Die beiden Hauptbibliotheken, die derzeit für diesen Prozess verwendet werden, sind:
‐ Puppeteer—Puppeteer ist eine JavaScript-Bibliothek, die mit einer kopflosen Implementierung von Chrome geliefert wird, mit der UI-Tests programmgesteuert im Hintergrund ausgeführt werden können. Ein Puppenspieler-Tutorial finden Sie hier.
– Selenium-Selenium ist ein Framework, das die Fernsteuerung eines Browsers über eine Bibliothek namens WebDriver ermöglicht. Ein Selenium-Tutorial finden Sie hier .
Es gibt mehr Arten von Tests als die hier aufgeführten. Andere haben möglicherweise andere Ziele; Beispielsweise versuchen Lasttests, Leistungsengpässe zu finden. Beachten Sie, dass die hier beschriebenen Tests manchmal unterschiedliche Namen erhalten. Die drei oben vorgestellten Typen sind die wichtigsten, die zu Beginn implementiert werden müssen. Die Verwendung eines von ihnen ist besser, als überhaupt keine automatisierten Tests zu verwenden.
Testmethoden
Testmethoden sind Möglichkeiten, über Tests nachzudenken. Die drei unten beschriebenen sind die am häufigsten verwendeten.
Test Driven Development (TDD)
TDD ist die am weitesten verbreitete und technischste Methode. Es wird empfohlen, dass Sie Ihre Tests schreiben, bevor Sie den eigentlichen Code schreiben, den Sie testen möchten. Da Sie einen Test nur für den Teil des Codes schreiben müssen, den Sie implementieren, ist die Art des Tests, den Sie schreiben, ein Komponententest.
Komponententests sind ziemlich granular, so dass die Verwendung dieser Methodik im Laufe der Zeit zu einer Anhäufung vieler Tests führt. Diese Realität, gepaart mit der Tatsache, dass TDD-Anfänger dazu neigen, triviale Tests zu schreiben, kann dazu führen, dass ein Haufen nutzloser Tests erstellt wird. Um dies zu vermeiden, ist es wichtig, Tests zu aktualisieren und zu bereinigen, wenn das Team mit TDD und mit Tests im Allgemeinen vertrauter geworden ist.
Es ist wichtig, die Tests häufig auszuführen, nicht nur in einer CI / CD-Pipeline, sondern auch lokal auf Ihrem Entwicklungscomputer. Schreiben Sie einen Test, führen Sie ihn aus, sehen Sie, dass er fehlschlägt, implementieren Sie genug, um den Test zu bestehen, und wiederholen Sie den Vorgang.
Weitere Informationen finden Sie in der Beschreibung von TDD von Agile Alliance.
Acceptance Test Driven Development (ATDD)
ATDD ist eine Modifikation von TDD, die sich mehr auf Business Cases und weniger auf die technische Implementierung konzentriert. Die Testtypen, die in dieser Methodik verwendet werden, sind meist Integrationstests, da häufig mehrere Teile des Systems zusammen verwendet werden müssen, um eine Geschäftsanforderung zu lösen.
Da die Tests weniger technisch sind, ist es auch ratsam, nicht technisch orientierte Personen in den Testprozess einzubeziehen. Product Owner und Kunden können helfen, die Business Cases zu definieren, damit ein Entwickler einen Test für sie schreiben kann. Wenn der Test nicht erfolgreich ausgeführt werden kann, ist klar, dass mehr Funktionalität implementiert werden muss.
ATDD arbeitet auf einer anderen Abstraktionsebene als TDD, sodass die beiden Methoden zusammen verwendet werden können.
Weitere Informationen finden Sie in der Beschreibung von TDD von Agile Alliance.
Behavior Driven Development (BDD)
BDD ist eine Mischung aus TDD und ATDD, deren Ziel es ist, das Beste aus beiden Welten zu nutzen, um das Gesamtsystem stabiler zu machen. BDD versucht, ein System mit Tests zu spezifizieren, die seine Verwendung veranschaulichen.
Wie ATDD versucht BDD, Geschäftsfälle zu erfassen. Es erfordert jedoch auch, dass Sie diese Anwendungsfälle mit den “5 Whys” in Frage stellen, da die “Whys” ein fehlender Teil in ATDD sind. Sicher, es ist besser, Kunden zu fragen, was sie wollen, anstatt sich ausschließlich auf Entwicklereingaben zu verlassen. Aber es ist auch wichtig, die Annahmen dieser beiden Gruppen in Frage zu stellen.
BDD ist auch eine Mischung aus TDD und ATDD im Sinne von Abstraktionsebenen. TDD testet nur die kleinen Teile Ihrer Anwendung und ATDD testet nur, wie diese Teile zusammenarbeiten. BDD erfordert, dass Sie diese Methodik auf das große Ganze Ihrer App und ihre kleinen Teile anwenden, wodurch BDD zu einem ganzheitlicheren Testansatz wird.
Weitere Informationen finden Sie in der Beschreibung von BDD von Agile Alliance.
Fazit
Obwohl keine Tests schrecklich sind, sind manuelle Tests besser und automatisierte Tests die besten.
Abhängig von der Größe Ihrer App kann ein manueller Test die Mitglieder des Entwicklungsteams für Tage oder sogar Wochen daran hindern, an anderen Projekten zu arbeiten, was Ihr Unternehmen Zeit und Geld kostet. Darüber hinaus kann die monotone Aufgabe, dieselben Interaktionen immer wieder auszuführen, zu Ausrutsch führen, die sich häufig in nicht erfassten Fehlern manifestieren.
Computer sind sehr gut darin, die gleiche Aufgabe immer wieder zu wiederholen, daher ist es eine gute Idee, Tests an ein Skript zu delegieren und die Zeit Ihrer Entwickler freizugeben. Wenn diese Tests in Ihre CI / CD-Pipeline integriert sind, können die bereits geschriebenen Tests nur implizit ausgeführt werden, wenn ein neues Commit in Ihren Repositorys landet.
Es ist eine gute Idee, frühzeitig eine Testmethode anzuwenden, da häufig die großen Probleme beim Einstieg darin bestehen, “was” und “wann” zu testen. Diese Methoden können helfen, einen Prozess zu klären, der das Schreiben von Tests für alle Teammitglieder konsistenter macht.
Leave a Reply