Jest 14.0: React Tree Snapshot Testing
Diese Seite wurde von PageTurner AI übersetzt (Beta). Nicht offiziell vom Projekt unterstützt. Fehler gefunden? Problem melden →
Eine der Philosophien von Jest ist es, eine integrierte "Null-Konfiguration"-Erfahrung zu bieten. Wir möchten das Schreiben nützlicher Tests so reibungslos wie möglich gestalten. Wir haben beobachtet, dass Entwickler, wenn sie einsatzbereite Tools erhalten, mehr Tests schreiben, was wiederum zu stabilen und gesunden Codebasen führt.
Eine große offene Frage war, wie man React-Tests effizient schreibt. Es gibt zahlreiche Tools wie ReactTestUtils und enzyme. Beide sind großartig und werden aktiv genutzt. Doch Entwickler berichteten uns häufig, dass sie mehr Zeit mit dem Schreiben eines Tests verbringen als mit der Komponente selbst. Dadurch haben viele komplett aufgehört, Tests zu schreiben, was schließlich zu Instabilitäten führte. Entwickler sagten uns, sie wollten nur sicherstellen, dass sich ihre Komponenten nicht unerwartet ändern.
Gemeinsam mit dem React-Team haben wir einen neuen Test-Renderer für React entwickelt und Snapshot-Testing zu Jest hinzugefügt. Betrachten Sie diesen Beispieltest für eine einfache Link-Komponente:
import renderer from 'react-test-renderer';
test('Link renders correctly', () => {
const tree = renderer
.create(<Link page="http://www.facebook.com">Facebook</Link>)
.toJSON();
expect(tree).toMatchSnapshot();
});
Beim ersten Ausführen dieses Tests erstellt Jest eine Snapshot-Datei, die so aussieht:
exports[`Link renders correctly 1`] = `
<a
className="normal"
href="http://www.facebook.com"
onMouseEnter={[Function bound _onMouseEnter]}
onMouseLeave={[Function bound _onMouseLeave]}>
Facebook
</a>
`;
Das Snapshot-Artefakt sollte zusammen mit Codeänderungen eingecheckt werden. Wir verwenden pretty-format, um Snapshots während der Code-Review lesbar zu machen. Bei nachfolgenden Testläufen vergleicht Jest einfach die gerenderte Ausgabe mit dem vorherigen Snapshot. Bei Übereinstimmung besteht der Test. Bei Abweichungen hat sich entweder die Implementierung geändert und der Snapshot muss mit jest -u aktualisiert werden, oder der Testrunner hat einen Fehler in Ihrem Code gefunden, der behoben werden sollte.
Wenn wir die Adresse ändern, auf die die Link-Komponente in unserem Beispiel verweist, gibt Jest diese Ausgabe aus:

Sie wissen nun, dass Sie entweder die Änderungen mit jest -u akzeptieren oder die Komponente korrigieren müssen, wenn die Änderungen unbeabsichtigt waren. Um diese Funktion auszuprobieren, klonen Sie bitte das Snapshot-Beispiel, modifizieren Sie die Link-Komponente und führen Sie Jest aus. Wir haben das React-Tutorial mit einer neuen Anleitung zum Snapshot-Testing aktualisiert.
Diese Funktion wurde von Ben Alpert und Cristian Carlesso entwickelt.
Experimentelle React Native-Unterstützung
Durch den Bau eines Test-Renderers ohne spezifische Plattformbindung können wir endlich eine vollständige, ungemockte Version von React Native unterstützen. Wir freuen uns, experimentelle React Native-Unterstützung für Jest über das jest-react-native-Paket einzuführen.
Sie können Jest mit react-native nutzen, indem Sie yarn add --dev jest-react-native ausführen und das Preset zu Ihrer Jest-Konfiguration hinzufügen:
"jest": {
"preset": "jest-react-native"
}
-
Beispiel-Pull-Request für snowflake, eine beliebte react-native Open-Source-Bibliothek.
Das Preset implementiert derzeit nur den minimalen Konfigurationssatz, der für den Einstieg in React Native-Tests notwendig ist. Wir hoffen auf Community-Beiträge zur Verbesserung dieses Projekts. Bitte testen Sie es und melden Sie Probleme oder senden Sie Pull-Requests!
Warum Snapshot-Testing?
Für Facebooks native Apps verwenden wir ein System namens "Snapshot-Testing": Ein Testsystem, das UI-Komponenten rendert, einen Screenshot aufnimmt und anschließend einen aufgezeichneten Screenshot mit Änderungen eines Entwicklers vergleicht. Wenn die Screenshots nicht übereinstimmen, gibt es zwei Möglichkeiten: Entweder ist die Änderung unerwartet, oder der Screenshot kann auf die neue Version der UI-Komponente aktualisiert werden.
Während dies die gewünschte Lösung für das Web war, fanden wir auch viele Probleme bei solchen End-to-End-Tests, die Snapshot-Integrationstests lösen:
-
Keine Flakiness: Da Tests in einem CLI-Runner statt in einem echten Browser oder auf einem echten Gerät laufen, muss der Testrunner nicht auf Builds warten, Browser starten, Seiten laden oder die UI steuern, um Komponenten in den erwarteten Zustand zu versetzen – was oft instabil ist und zu verrauschten Testergebnissen führt.
-
Schnelle Iterationsgeschwindigkeit: Entwickler möchten Ergebnisse in weniger als einer Sekunde sehen, nicht nach Minuten oder Stunden. Wenn Tests nicht schnell laufen wie in den meisten End-to-End-Frameworks, führen Entwickler sie erst gar nicht aus oder schreiben sie von vornherein nicht.
-
Debugging: Es ist einfach, im Code eines Integrationstests zu debuggen, anstatt Szenarien für Screenshot-Tests nachzustellen und visuelle Differenzen zu analysieren.
Da wir Snapshot-Tests auch außerhalb von Jest für nützlich halten, haben wir die Funktion in ein eigenes jest-snapshot-Paket ausgegliedert. Wir arbeiten gerne mit der Community zusammen, um es generischer zu machen, damit es in andere Testrunner integriert werden kann und Konzepte/Infrastruktur teilen kann.
Abschließend ein Zitat eines Facebook-Entwicklers über seine Erfahrungen mit Snapshot-Tests:
„Eine der größten Herausforderungen meines Projekts war die Synchronisierung von Eingabe- und Ausgabedateien für jeden Testfall. Jede kleine Funktionsänderung konnte alle Ausgabedateien verändern. Mit Snapshot-Tests brauche ich keine Ausgabedateien mehr – die Snapshots werden kostenlos von Jest generiert! Ich kann einfach prüfen, wie Jest die Snapshots aktualisiert, anstatt Änderungen manuell vorzunehmen.“ – Kyle Davis, Entwickler von fjs.
Was kommt als Nächstes für Jest?
Kürzlich ist Aaron Abramov dem Jest-Team beigetreten, um unsere Unit- und Integrationstest-Infrastruktur für Facebooks Werbeprodukte zu verbessern. In den nächsten Monaten plant das Jest-Team wichtige Verbesserungen in diesen Bereichen:
-
Jasmine ersetzen: Jasmine bremst uns aus und wird nicht mehr aktiv weiterentwickelt. Wir beginnen damit, alle Jasmine-Matcher zu ersetzen und freuen uns darauf, neue Funktionen hinzuzufügen und diese Abhängigkeit zu entfernen.
-
Code Coverage: Als Jest ursprünglich erstellt wurde, gab es Tools wie Babel noch nicht. Unsere Code-Coverage-Unterstützung hat viele Edge Cases und funktioniert nicht immer zuverlässig. Wir schreiben sie neu, um alle aktuellen Probleme zu beheben.
-
Developer Experience: Von verbessertem Setup über Debugging-Erlebnis bis zu CLI-Verbesserungen und mehr Dokumentation.
-
Mocking: Das Mock-System, besonders bei manuellen Mocks, ist verwirrend und funktioniert nicht optimal. Wir wollen es stringenter und verständlicher gestalten.
-
Performance: Weitere Performance-Verbesserungen speziell für sehr große Codebasen werden bearbeitet.
Wie immer: Bei Fragen oder wenn ihr mithelfen möchtet, meldet euch bei uns!
