Ein praktischer Leitfaden zum Testen von React-Anwendungen mit Jest
Veröffentlicht: 2022-03-10In diesem Artikel stelle ich Ihnen ein React-Testtool namens Jest zusammen mit der beliebten Bibliothek Enzyme vor, die zum Testen von React-Komponenten entwickelt wurde. Ich stelle Ihnen Jest-Testtechniken vor, darunter: Ausführen von Tests, Testen von React-Komponenten, Snapshot-Tests und Mocking. Wenn Sie neu beim Testen sind und sich fragen, wie Sie anfangen sollen, werden Sie dieses Tutorial hilfreich finden, da wir mit einer Einführung in das Testen beginnen. Am Ende sind Sie einsatzbereit und testen React-Anwendungen mit Jest und Enzyme. Sie sollten mit React vertraut sein, um diesem Tutorial folgen zu können.
Eine kurze Einführung in das Testen
Beim Testen wird zeilenweise überprüft, wie Ihr Code ausgeführt wird. Eine Reihe von Tests für eine Anwendung umfasst verschiedene Codebits, um zu überprüfen, ob eine Anwendung erfolgreich und fehlerfrei ausgeführt wird. Das Testen ist auch praktisch, wenn Aktualisierungen am Code vorgenommen werden. Nachdem Sie einen Codeabschnitt aktualisiert haben, können Sie einen Test ausführen, um sicherzustellen, dass das Update die bereits in der Anwendung vorhandene Funktionalität nicht beeinträchtigt.
Warum testen?
Es ist gut zu verstehen, warum wir etwas tun, bevor wir es tun. Warum also testen und was ist sein Zweck?
- Der erste Zweck des Testens besteht darin, eine Regression zu verhindern. Regression ist das erneute Auftreten eines Fehlers, der zuvor behoben wurde. Es bewirkt, dass eine Funktion nicht mehr wie beabsichtigt funktioniert, nachdem ein bestimmtes Ereignis eintritt.
- Testen sichert die Funktionalität komplexer Komponenten und modularer Anwendungen.
- Das Testen ist für die effektive Leistung einer Softwareanwendung oder eines Produkts erforderlich.
Das Testen macht eine App robuster und weniger fehleranfällig. Auf diese Weise können Sie überprüfen, ob Ihr Code das tut, was Sie wollen, und ob Ihre App wie beabsichtigt für Ihre Benutzer funktioniert.
Gehen wir die Arten von Tests durch und was sie tun.
Gerätetest
Bei dieser Testart werden einzelne Einheiten oder Komponenten der Software getestet. Eine Einheit kann eine einzelne Funktion, Methode, Prozedur, Modul oder Objekt sein. Ein Komponententest isoliert einen Codeabschnitt und überprüft seine Korrektheit, um zu validieren, dass jede Einheit des Softwarecodes wie erwartet funktioniert.
Beim Unit-Test werden einzelne Prozeduren oder Funktionen auf einwandfreie Funktion getestet und alle Komponenten einzeln getestet. Beispielsweise würde das Testen einer Funktion oder ob eine Anweisung oder Schleife in einem Programm ordnungsgemäß funktioniert, in den Anwendungsbereich des Unit-Tests fallen.
Komponententest
Komponententests verifizieren die Funktionalität eines einzelnen Teils einer Anwendung. Tests werden an jeder Komponente isoliert von anderen Komponenten durchgeführt. Im Allgemeinen bestehen React-Anwendungen aus mehreren Komponenten, sodass beim Komponententest diese Komponenten einzeln getestet werden.
Stellen Sie sich zum Beispiel eine Website vor, die verschiedene Webseiten mit vielen Komponenten hat. Jede Komponente hat ihre eigenen Unterkomponenten. Das Testen jedes Moduls ohne Berücksichtigung der Integration mit anderen Komponenten wird als Komponententest bezeichnet.
Solche Tests in React erfordern ausgefeiltere Tools. Wir bräuchten also Jest und manchmal ausgefeiltere Tools wie Enzyme, auf die wir später noch kurz eingehen werden.
Snapshot-Test
Ein Snapshot-Test stellt sicher, dass sich die Benutzeroberfläche (UI) einer Webanwendung nicht unerwartet ändert. Es erfasst den Code einer Komponente zu einem bestimmten Zeitpunkt, sodass wir die Komponente in einem Zustand mit jedem anderen möglichen Zustand vergleichen können, den sie einnehmen könnte.
Wir werden in einem späteren Abschnitt mehr über Snapshot-Tests erfahren.
Vor- und Nachteile des Testens
Tests sind großartig und sollten durchgeführt werden, aber sie haben Vor- und Nachteile.
Vorteile
- Es verhindert eine unerwartete Regression.
- Es ermöglicht dem Entwickler, sich auf die aktuelle Aufgabe zu konzentrieren, anstatt sich um die Vergangenheit zu sorgen.
- Es ermöglicht den modularen Aufbau einer Anwendung, die ansonsten zu komplex zu erstellen wäre.
- Es reduziert die Notwendigkeit einer manuellen Überprüfung.
Nachteile
- Sie müssen mehr Code schreiben sowie debuggen und warten.
- Unkritische Testfehler können dazu führen, dass die App im Hinblick auf die kontinuierliche Integration abgelehnt wird.
Einführung in den Scherz
Jest ist ein wunderbares JavaScript-Testframework mit Fokus auf Einfachheit. Es kann mit npm oder Yarn installiert werden. Jest passt in eine breitere Kategorie von Dienstprogrammen, die als Test Runner bekannt sind. Es funktioniert hervorragend für React-Anwendungen, aber auch außerhalb von React-Anwendungen.
Enzyme ist eine Bibliothek, die zum Testen von React-Anwendungen verwendet wird. Es wurde zum Testen von Komponenten entwickelt und ermöglicht das Schreiben von Behauptungen, die Aktionen simulieren, die bestätigen, ob die Benutzeroberfläche ordnungsgemäß funktioniert.
Jest und Enzym ergänzen sich so gut, daher werden wir in diesem Artikel beide verwenden.
Ablauf eines Tests mit Jest
In diesem Abschnitt werden wir Jest installieren und Tests schreiben. Wenn Sie neu bei React sind, empfehle ich die Verwendung der Create React App, da sie sofort einsatzbereit ist und mit Jest ausgeliefert wird.
npm init react-app my-app
Wir müssen Enzyme **** und enzyme-adapter-react-16
mit React react-test-renderer
installieren (die Nummer sollte auf der Version von React basieren, die Sie verwenden).
npm install --save-dev enzyme enzyme-adapter-react-16 react-test-renderer
Nachdem wir unser Projekt sowohl mit Jest als auch mit Enzyme erstellt haben, müssen wir eine setupTest.js
-Datei im src
-Ordner des Projekts erstellen. Die Datei sollte so aussehen:
import { configure } from "enzyme"; import Adapter from "enzyme-adapter-react-16"; configure({ adapter: new Adapter() });
Dies importiert Enzyme und richtet den Adapter ein, um unsere Tests auszuführen.
Bevor wir fortfahren, lernen wir einige Grundlagen. Einige wichtige Dinge werden in diesem Artikel häufig verwendet, und Sie müssen sie verstehen.
-
it
odertest
Sie würden eine Funktion an diese Methode übergeben, und der Test-Runner würde diese Funktion als einen Block von Tests ausführen. -
describe
Diese optionale Methode dient zum Gruppieren einer beliebigen Anzahl vonit
odertest
Anweisungen. -
expect
Dies ist die Bedingung, die der Test bestehen muss. Er vergleicht den empfangenen Parameter mit dem Matcher. Es gibt Ihnen auch Zugriff auf eine Reihe von Matchern, mit denen Sie verschiedene Dinge validieren können. Sie können mehr darüber in der Dokumentation lesen. -
mount
Diese Methode rendert das vollständige DOM, einschließlich der untergeordneten Komponenten der übergeordneten Komponente, in der wir die Tests ausführen. -
shallow
Dadurch werden nur die einzelnen Komponenten gerendert, die wir testen. Untergeordnete Komponenten werden nicht gerendert. Dies ermöglicht es uns, Komponenten isoliert zu testen.
Erstellen einer Testdatei
Woher weiß Jest, was eine Testdatei ist und was nicht? Die erste Regel lautet, dass alle Dateien, die in einem beliebigen Verzeichnis mit dem Namen __test__
werden, als Test betrachtet werden. Wenn Sie eine JavaScript-Datei in einem dieser Ordner ablegen, wird Jest versuchen, sie auszuführen, wenn Sie Jest anrufen, im Guten wie im Schlechten. Die zweite Regel ist, dass Jest jede Datei mit dem Suffix .spec.js
oder .test.js
. Es durchsucht die Namen aller Ordner und aller Dateien in Ihrem gesamten Repository.
Lassen Sie uns unseren ersten Test für eine React-Minianwendung erstellen, die für dieses Tutorial erstellt wurde. Sie können es auf GitHub klonen. Führen Sie npm install
aus, um alle Pakete zu installieren, und starten Sie dann mit npm start
die App. Weitere Informationen finden Sie in der Datei README.md
.
Öffnen App.test.js
, um unseren ersten Test zu schreiben. Überprüfen Sie zunächst, ob unsere App-Komponente korrekt gerendert wird und ob wir eine Ausgabe angegeben haben:
it("renders without crashing", () => { shallow(<App />); }); it("renders Account header", () => { const wrapper = shallow(<App />); const welcome = <h1>Display Active Users Account Details</h1>; expect(wrapper.contains(welcome)).toEqual(true); });
Im obigen Test überprüft der erste Test mit shallow
, ob unsere App-Komponente korrekt gerendert wird, ohne abzustürzen. Denken Sie daran, dass die shallow
Methode nur eine einzelne Komponente ohne untergeordnete Komponenten rendert.
Der zweite Test prüft, ob wir in unserer App-Komponente eine h1
-Tag-Ausgabe von „Display Active User Account“ mit einem Jest-Matcher von toEqual
.
Führen Sie nun den Test durch:
npm run test /* OR */ npm test
Die Ausgabe in Ihrem Terminal sollte so aussehen:
PASS src/App.test.js √ renders without crashing (34ms) √ renders Account header (13ms) Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 0 total Time: 11.239s, estimated 16s Ran all test suites related to changed files. Watch Usage: Press w to show more.
Wie Sie sehen können, hat unser Test bestanden. Es zeigt, dass wir eine Testsuite namens App.test.js
haben, mit zwei erfolgreichen Tests, als Jest lief. Wir werden später über Snapshot-Tests sprechen, und Sie werden auch ein Beispiel für einen fehlgeschlagenen Test sehen.
Einen Test überspringen oder isolieren
Das Überspringen oder Isolieren eines Tests bedeutet, dass beim Ausführen von Jest ein bestimmter markierter Test nicht ausgeführt wird.
it.skip("renders without crashing", () => { shallow(<App />); }); it("renders Account header", () => { const wrapper = shallow(<App />); const header = <h1>Display Active Users Account Details</h1>; expect(wrapper.contains(header)).toEqual(true); });
Unser erster Test wird übersprungen, da wir die skip
-Methode verwendet haben, um den Test zu isolieren. Es wird also nicht ausgeführt oder Änderungen an unserem Test vorgenommen, wenn Jest ausgeführt wird. Nur der zweite läuft. Sie können auch it.only()
verwenden.
Es ist etwas frustrierend, Änderungen an einer Testdatei vorzunehmen und dann npm test
erneut manuell ausführen zu müssen. Jest hat eine nette Funktion namens Überwachungsmodus, die auf Dateiänderungen achtet und entsprechende Tests durchführt. Um Jest im Überwachungsmodus auszuführen, können Sie npm test -- --watch
oder jest --watch
. Ich würde auch empfehlen, Jest für den Rest dieses Tutorials im Terminalfenster laufen zu lassen.
Spottfunktion
Ein Mock ist ein überzeugendes Duplikat eines Objekts oder Moduls ohne echtes Innenleben. Es mag ein bisschen Funktionalität haben, aber im Vergleich zur Realität ist es ein Schein. Es kann automatisch von Jest oder manuell erstellt werden.
Warum sollten wir spotten? Mocking reduziert die Anzahl der Abhängigkeiten – d. h. die Anzahl der zugehörigen Dateien, die geladen und analysiert werden müssen, wenn ein Test ausgeführt wird. Wenn Sie also viele Mocks verwenden, werden Tests schneller ausgeführt.
Scheinfunktionen werden auch als „Spione“ bezeichnet, da Sie damit das Verhalten einer Funktion ausspionieren können, die direkt von einem anderen Code aufgerufen wird, anstatt nur die Ausgabe zu testen.
Es gibt zwei Möglichkeiten, eine Funktion zu simulieren: entweder durch Erstellen einer Mock-Funktion, um sie im Testcode zu verwenden, oder durch Schreiben eines manuellen Mocks, um eine Modulabhängigkeit zu überschreiben.
Manuelle Mocks **** werden verwendet, um Funktionen mit Mock-Daten auszustatten. Anstatt beispielsweise auf eine Remote-Ressource wie eine Website oder eine Datenbank zuzugreifen, möchten Sie möglicherweise einen manuellen Mock erstellen, der es Ihnen ermöglicht, gefälschte Daten zu verwenden.
Wir werden im nächsten Abschnitt eine Scheinfunktion verwenden.
Testen von Reaktionskomponenten
Der Abschnitt wird all das Wissen kombinieren, das wir bisher zum Testen von React-Komponenten gewonnen haben. Beim Testen muss sichergestellt werden, dass sich die Ausgabe einer Komponente nicht unerwartet in etwas anderes geändert hat. Die richtige Konstruktion von Komponenten ist bei weitem der effektivste Weg, um erfolgreiche Tests sicherzustellen.
Eine Sache, die wir tun können, ist Komponentenprops zu testen – insbesondere zu testen, ob Props von einer Komponente an eine andere weitergegeben werden. Jest und die Enzyme-API ermöglichen es uns, eine Mock-Funktion zu erstellen, um zu simulieren, ob Requisiten zwischen Komponenten weitergegeben werden.
Wir müssen die Benutzerkonto-Requisiten von der Haupt- App
-Komponente an die Account
-Komponente übergeben. Wir müssen Benutzerkontodaten an das Account
, um das aktive Konto der Benutzer zu erstellen. Hier kommt das Spotten ins Spiel, das es uns ermöglicht, unsere Komponenten mit gefälschten Daten zu testen.
Lassen Sie uns ein Mock für die user
-Requisiten erstellen:
const user = { name: "Adeneye David", email: "[email protected]", username: "Dave", };
Wir haben in unserer Testdatei eine manuelle Mock-Funktion erstellt und diese um die Komponenten gewickelt. Nehmen wir an, wir testen eine große Datenbank von Benutzern. Von einem direkten Zugriff auf die Datenbank aus unserer Testdatei ist abzuraten. Stattdessen erstellen wir eine Mock-Funktion, die es uns ermöglicht, gefälschte Daten zum Testen unserer Komponente zu verwenden.
describe(" ", () => { it("accepts user account props", () => { const wrapper = mount(<Account user={user} />); expect(wrapper.props().user).toEqual(user); }); it("contains users account email", () => { const wrapper = mount(<Account user={user} />); const value = wrapper.find("p").text(); expect(value).toEqual("[email protected]"); }); });
describe(" ", () => { it("accepts user account props", () => { const wrapper = mount(<Account user={user} />); expect(wrapper.props().user).toEqual(user); }); it("contains users account email", () => { const wrapper = mount(<Account user={user} />); const value = wrapper.find("p").text(); expect(value).toEqual("[email protected]"); }); });
Wir haben oben zwei Tests, und wir verwenden eine describe
, die die zu testende Komponente übernimmt. Indem wir die Requisiten und Werte angeben, von denen wir erwarten, dass sie durch den Test bestanden werden, können wir fortfahren.
Im ersten Test prüfen wir, ob die Requisiten, die wir an die gemountete Komponente übergeben haben, mit den oben erstellten Mock-Requisiten übereinstimmen.
Für den zweiten Test übergeben wir die Benutzerprops an die gemountete Account
-Komponente. Dann prüfen wir, ob wir das <p>
-Element finden können, das dem entspricht, was wir in der Account
Komponente haben. Wenn wir die Testsuite ausführen, sehen Sie, dass der Test erfolgreich ausgeführt wird.
Wir können auch den Zustand unserer Komponente testen. Prüfen wir, ob der Zustand der Fehlermeldung gleich null ist:
it("renders correctly with no error message", () => { const wrapper = mount( ); expect(wrapper.state("error")).toEqual(null); });
it("renders correctly with no error message", () => { const wrapper = mount( ); expect(wrapper.state("error")).toEqual(null); });
In diesem Test prüfen wir mithilfe eines toEqual()
-Matchers, ob der Zustand unseres Komponentenfehlers gleich null ist. Wenn in unserer App eine Fehlermeldung angezeigt wird, schlägt der Test bei der Ausführung fehl.
Im nächsten Abschnitt werden wir durchgehen, wie man React-Komponenten mit Snapshot-Tests testet, einer weiteren erstaunlichen Technik.
Snapshot-Tests
Beim Snapshot-Testen wird der Code einer Komponente zu einem bestimmten Zeitpunkt erfasst, um ihn mit einer neben dem Test gespeicherten Referenz-Snapshot-Datei zu vergleichen. Es wird verwendet, um Änderungen in der Benutzeroberfläche einer App zu verfolgen.
Die eigentliche Codedarstellung eines Snapshots ist eine JSON-Datei, und diese JSON enthält eine Aufzeichnung darüber, wie die Komponente aussah, als der Snapshot erstellt wurde. Während eines Tests vergleicht Jest den Inhalt dieser JSON-Datei mit der Ausgabe der Komponente während des Tests. Wenn sie übereinstimmen, ist der Test bestanden; Wenn sie dies nicht tun, schlägt der Test fehl.
Um einen Enzyme-Wrapper in ein Format umzuwandeln, das mit Jest-Snapshot-Tests kompatibel ist, müssen wir enzyme-to-json
installieren:
npm install --save-dev enzyme-to-json
Lassen Sie uns unseren Snapshot-Test erstellen. Wenn wir es das erste Mal ausführen, wird der Snapshot des Codes dieser Komponente erstellt und in einem neuen Ordner __snapshots__
im src
-Verzeichnis gespeichert.
it("renders correctly", () => { const tree = shallow(<App />); expect(toJson(tree)).toMatchSnapshot(); });
Wenn der obige Test erfolgreich ausgeführt wird, wird die aktuelle UI-Komponente mit der vorhandenen verglichen.
Lassen Sie uns nun den Test durchführen:
npm run test
Wenn die Testsuite ausgeführt wird, wird ein neuer Snapshot generiert und im Ordner __snapshots__
. Wenn wir anschließend einen Test durchführen, prüft Jest, ob die Komponenten mit dem Snapshot übereinstimmen.
Wie im vorherigen Abschnitt erläutert, wird diese shallow
Methode aus dem Enzyme-Paket verwendet, um eine einzelne Komponente und sonst nichts zu rendern. Es werden keine untergeordneten Komponenten gerendert. Vielmehr bietet es uns eine gute Möglichkeit, Code zu isolieren und beim Debuggen bessere Informationen zu erhalten. Eine andere Methode namens mount
wird verwendet, um das vollständige DOM zu rendern, einschließlich der untergeordneten Komponenten der übergeordneten Komponente, in der wir die Tests ausführen.
Wir können auch unseren Snapshot aktualisieren. Nehmen wir einige Änderungen an unserer Komponente vor, damit unser Test fehlschlägt, was passieren wird, weil die Komponente nicht mehr dem entspricht, was wir in der Snapshot-Datei haben. Dazu ändern wir das <h3>
-Tag in unserer Komponente von <h3> Loading...</h3>
in <h3>Fetching Users...</h3>
. Wenn der Test läuft, erhalten wir Folgendes im Terminal:
FAIL src/App.test.js (30.696s) × renders correctly (44ms) ● renders correctly expect(received).toMatchSnapshot() Snapshot name: `renders correctly 1 - Snapshot + Received
7 | it("Rendert korrekt", () => { 8 | konstanter Wrapper = flach ( FAIL src/App.test.js (30.696s) × renders correctly (44ms) ● renders correctly expect(received).toMatchSnapshot() Snapshot name: `renders correctly 1 - Snapshot + Received
Kontodetails aktiver Benutzer anzeigen
- Wird geladen... + Benutzer werden abgerufen...
); > 9 | Expect(toJson(Wrapper)).toMatchSnapshot(); | ^ 10 | }); 11 | 12 | /* it("Rendert ohne Absturz", () => { bei Objekt. (src/App.test.js:9:27) › 1 Schnappschuss fehlgeschlagen. Snapshot-Zusammenfassung › 1 Snapshot aus 1 Testsuite ist fehlgeschlagen. Überprüfen Sie Ihre Codeänderungen oder drücken Sie "u", um sie zu aktualisieren. Testsuiten: 1 fehlgeschlagen, 1 insgesamt Tests: 1 fehlgeschlagen, 1 insgesamt Schnappschüsse: 1 fehlgeschlagen, 1 insgesamt Zeit: 92,274 s Alle Testsuiten im Zusammenhang mit geänderten Dateien ausgeführt. Nutzung ansehen: Drücken Sie w, um mehr anzuzeigen.
Wenn wir möchten, dass unser Test bestanden wird, würden wir den Test entweder in seinen vorherigen Zustand zurückversetzen oder die Snapshot-Datei aktualisieren. In der Befehlszeile gibt Jest Anweisungen zum Aktualisieren des Snapshots. Drücken Sie zuerst w
in der Befehlszeile, um mehr anzuzeigen, und drücken Sie dann u
, um den Schnappschuss zu aktualisieren.
› Press u to update failing snapshots.
Wenn wir u
drücken, um den Snapshot zu aktualisieren, wird der Test bestanden.
Fazit
Ich hoffe, es hat Ihnen Spaß gemacht, dieses Tutorial durchzuarbeiten. Wir haben einige Jest-Testtechniken unter Verwendung der Enzymtestbibliothek gelernt. Ich habe Sie auch in den Prozess des Ausführens eines Tests, des Testens von React-Komponenten, des Mockings und des Snapshot-Tests eingeführt. Wenn Sie Fragen haben, können Sie diese unten im Kommentarbereich hinterlassen, und ich beantworte gerne alle Fragen und bearbeite alle Probleme mit Ihnen.
Ressourcen und weiterführende Literatur
- Witzige Dokumentation
- Enzymdokumentation
- „So testen Sie React-Komponenten: Der vollständige Leitfaden“, Mohammad Iqbal, freeCodeCamp
- „Reagieren mit Jest und Enzym testen“, Dominic Fraser, CodeClan