Einfache JavaScript-Komponententests in WordPress mit Jest
WordPress hat eine lange Geschichte von Unit-Tests seines PHP-Codes. Das Schreiben von JavaScript-Unit-Tests und Integrationstests für den Code in Themes und Plugins genießt jedoch nicht den gleichen Stellenwert. Sehen wir uns an, wie Sie das JavaScript in unseren WordPress-Plugins und -Designs mit Jest testen.
Dies sind die Inhalte, die wir in diesem Artikel behandeln werden:
JavaScript-Einheitentests in WordPress
Warum also Unit-Tests und Integrationstests schreiben? Sie sind großartig, um sicherzustellen, dass eine Funktion, eine Klassenmethode oder sogar eine React-Komponente das tut, was sie tun sollen. Es hilft, Fehler im Code zu erkennen und hilft auch, die Integrität zu bewahren, wenn später Änderungen in den Code eingeführt werden, indem überprüft wird, ob er nach der Aktualisierung immer noch wie beabsichtigt funktioniert.
WordPress- Plugins und -Designs sind größtenteils in PHP geschrieben und können die PHPUnit-Suite verwenden, um Tests durchzuführen, Behauptungen aufzustellen, Funktionen zu verspotten und mehr. Das Handbuch hat sogar einen Abschnitt, der erklärt, wie man Unit-Tests mit der WP-CLI schnell einrichtet .
Für JavaScript gibt es im Handbuch eine Seite zum Ausführen von QUnit-Tests, obwohl es mehr um das Testen des JavaScript-Codes im WordPress-Kern geht.
Während nichts davon für JavaScript in WordPress standardisiert ist, können wir mit der Jest-Testsuite großartige Unit-Tests schreiben. In diesem Artikel lernen wir, wie man JavaScript-Unit-Tests für ein Beispiel-Plugin schreibt, das 5 Posts über die WP-REST-API mit der fetch
Funktion von JavaScript lädt und sie in einem bestimmten DOM-Element auf der Seite rendert.
Vorteile der Verwendung von Jest für JavaScript-Einheitentests in WordPress
In der Vergangenheit umfasste das Schreiben von JavaScript-Unit-Tests das Einrichten von Mocha zum Ausführen von Tests, Chai zum Aufstellen von Behauptungen und Sinon zum Mocken von Funktionen und Ausspionieren. Obwohl sie eine große Flexibilität bieten, ist es viel komplexer, mit drei Paketen zu arbeiten als mit einem. Jest bietet all dies in einem einzigen Paket:
- Sie können Tests ausführen, indem Sie sie mit
describe
undit
oder deklarierentest
- Sie können Aussagen mit
expect
und machentoBe
,toHaveLength
und viele mehr - Sie können Funktionen verspotten und sie ausspionieren, und es gibt mehrere Möglichkeiten, dies zu tun
Bevor es weitergeht
Damit sich dieser Artikel auf das Testen mit Jest konzentriert, gibt es zusätzliche Setups außerhalb des Testprozesses wie Babel oder Webpack, die hier nicht behandelt werden. All dies finden Sie im WP Jest Tests Repo, das diesen Artikel begleitet. Um den Kontext zu wahren, wird jeder Abschnitt auf eine der relevanten Dateien verlinken, die wir schreiben werden.
Überblick über die PHP-Seite
Das PHP für das Beispiel-Plug -in, das wir verwenden werden, um zu lernen, wie man die JavaScript-Einheitentests schreibt, ist ziemlich standardisiert. Die einzigen interessanten Zeilen sind die, wenn wir unsere JavaScript-Datei in die Warteschlange stellen und ein Inline-Skript hinzufügen, um ihr Variablen zu übergeben:
Nachdem wir unsere JavaScript-Datei angefragt haben, fügen wir eine globale Variable wpJestTests
mit hinzu wp_add_inline_script()
. Diese Variable ist besonders interessant und schwierig zu handhaben, da sie sich außerhalb unserer JavaScript-Datei befindet und wir sie in unseren Tests mocken müssen.
Richten Sie Jest-Tests ein
Wir müssen zuerst npm
in unserem Plugin-Projekt initialisieren, um Jest damit installieren zu können. Navigieren Sie in der Befehlszeile zu Ihrem Plugin-Ordner und führen Sie Folgendes aus:
npm init
und gehen Sie die Reihe der Eingabeaufforderungen hier durch
Bearbeiten Sie die erstellte Datei package.json und fügen Sie einen neuen Eintrag hinzu, um unsere Tests im scripts
Abschnitt auszuführen:
"test": "jest"
Dies ist der Befehl, mit dem wir Jest anweisen, unsere JavaScript-Einheitentests auszuführen. Dies ist ein einmaliger Lauf, aber Jest unterstützt auch das Beobachten von Dateien, sodass Sie einen zusätzlichen eingeben können:
"test-watch": "jest --watch"
Installieren Sie jetzt Jest als Entwicklungsabhängigkeit, indem Sie es ausführen
npm install -D jest
Erstellen Sie während der Installation eine Datei mit dem Namen jest.config.js
. Dies enthält die gesamte erforderliche Konfiguration. Fügen Sie Folgendes hinzu:
module.exports = {
verbose: true,
setupFiles: [
'/__mocks__/globals.js'
],
moduleNameMapper: {
'.(css|less|sass|scss)$': '/__mocks__/styleMock.js'
}
};
Lassen Sie uns jeden durchgehen:
verbose
: Gibt an, ob jeder einzelne Test während des Laufs gemeldet werden soll. Alle Fehler werden auch nach der Ausführung unten angezeigt. Beachten Sie, dass, wenn nur eine Testdatei ausgeführt wird, standardmäßigtrue
.setupFiles
: eine Liste von Pfaden zu Modulen, die Code ausführen, um die Testumgebung zu konfigurieren oder einzurichten. Jede setupFile wird einmal pro Testdatei ausgeführt. Da jeder Test in seiner eigenen Umgebung läuft, werden diese Skripte unmittelbar vor der Ausführung des Testcodes in der Testumgebung ausgeführt. Wir werden dies verwenden, um globale Variablen zu deklarieren, die von PHP und WordPress mit Befehlen wiewp_add_inline_script
oder gerendert werdenwp_localize_script
.moduleNameMapper
: Dies ist eine Zuordnung von regulären Ausdrücken zu Modulnamen (oder Arrays von Modulnamen), die es ermöglichen, statische Ressourcen, wie Bilder oder Stile, mit einem einzigen Modul auszusondern.
Sie haben sicherlich den Verweis bemerkt: Dies ist ein spezielles Token, das von Jest durch das Stammverzeichnis Ihres Projekts ersetzt wird, was normalerweise der Speicherort Ihrer package.json
.
Wir werden in den nächsten beiden Abschnitten ausführlich darauf eingehen, aber erstellen Sie zuerst den Ordner und diese beiden Dateien, auf die oben verwiesen wird:
- Erstellen Sie einen Ordner mit dem Namen
__mocks__
- Erstellen Sie in dem Ordner die Dateien
styleMock.js
undglobals.js
Import von Mock-Styles für Jest-Tests
Wenn Sie wie dieses Plugin Webpack verwenden, um alles einschließlich Stile zu kompilieren, und Sie die .scss
Datei in die .js
Datei importieren:
import './main.scss';
Sie müssen styleMock.js verwenden, um SASS-Dateien zu simulieren, wenn Sie sie in unsere JavaScript-Datei importieren, sonst stürzt Jest ab, da es das Modul nicht auflösen kann. Sie brauchen nicht viel für diese Datei, fügen Sie einfach hinzu
Jest verwendet dieses Mock jedes Mal, wenn es einen .scss
Import findet, und ordnet sie dem Mock zu, sodass Sie mit Tests fortfahren können, ohne sich um die Stile kümmern zu müssen.
Richten Sie Globals für Jest ein
Lassen Sie uns jetzt in der globals.js -Datei arbeiten. Einer der Vorteile der Verwendung von Jest ist, dass es bereits mit einer bereits konfigurierten jsdom
, einer reinen JavaScript-Implementierung von Webstandards, ausgeliefert wird, die eine DOM-Umgebung simuliert, als ob Sie sich im Browser befänden, und wir werden sie verwenden, um DOM-Elemente zu simulieren für unsere Tests.
Erstellen Sie einen Ordner __mocks__
und eine globals.js
Datei darin. Fügen Sie dies der Datei hinzu:
import { JSDOM } from 'jsdom';
const dom = new JSDOM();
global.document = dom.window.document;
global.window = dom.window;
global.window.wpJestTests = undefined;
Dadurch werden einige Objekte und Methoden deklariert und verspottet, die Sie später in Ihren Tests verwenden werden. Letzteres ist von besonderem Interesse
global.window.wpJestTests = undefined;
Dies ist die globale Variable, die wir mit geschrieben haben wp_add_inline_script
. Sie müssen es als globale Variable simulieren, um es in Ihren Tests verwenden zu können.
Übersicht über die JavaScript-Datei
Das WordPress-Plugin hat eine einzelne JavaScript-Datei main.js in einem /src
Ordner. Dies wird später transpiliert und in einer /js/front.js
Datei ausgegeben, die PHP lädt. Das JavaScript lädt fünf WordPress-Beiträge mithilfe von fetch
, einer Standard-JavaScript-Funktion, über die WP-REST-API und fügt seinen Titel mit einem Link zum Beitrag in eine div.entry-content
.
Sie werden die Funktion exportieren, die die ganze Arbeit erledigt:
damit Sie es in Ihren Tests in Jest verwenden können.
Endlich JavaScript Unit Tests mit Jest schreiben!
Jetzt können Sie mit dem Schreiben von Tests beginnen! Jest kann Tests auf viele Arten finden:
- wenn der Dateiname ist
test.js
- oder dem Namen der zu testenden Datei vorangestellt ist, wie z
main.test.js
- wenn es sich
.js
um Dateien handelt, die sich in einem Ordner mit dem Namen befinden__tests__
Erstellen Sie den __tests__
Ordner und darin eine front.test.js
. Sie können die fertige JavaScript-Datei für die Jest-Tests im Companion Repo sehen. Gehen wir es in Blöcken durch. Die erste Zeile importiert die JS-Datei, die wir testen möchten:
import { wpJestTestsInit } from '../src/main';
Als nächstes löschen wir alle Mocks, damit wir nie mit schmutzigen Mocks laufen, die Werte aus früheren Tests enthalten. Dies kann zu Fehlern führen, da wir beispielsweise, wenn wir ausspionieren, wie oft eine verspottete Funktion aufgerufen wurde, einen falschen Messwert erhalten, wenn wir den Schein nicht zwischen Test und Test löschen:
Der erste Test, den wir schreiben, macht grundlegende Behauptungen, wenn einige Dinge fehlschlagen. Wenn zum Beispiel die globale wpJestTests
Variable, mit der wir geschrieben haben wp_add_inline_script
, aus irgendeinem Grund nicht geschrieben wurde:
In diesem Code
describe
erstellt eine Gruppe, die aus mehreren verwandten Tests bestehttest
ist, was tatsächlich einen Test durchführtexpect
umschließt unser Testsubjekt und bietet Zugriff auf eine Reihe von „Matchern”, mit denen Sie verschiedene Behauptungen über seinen Inhalt aufstellen könnentoBe
ist einer dieser Matcher. Jest enthält viele Matcher und es gibt sogar andere, die Sie mit einem Paket eines Drittanbieters hinzufügen können .
Der erste Test definiert nichts für wpJestTests
, also ist sein Wert das, was Sie in definiert haben globals.js
. Da es ist undefined
, können wir nicht arbeiten, also wollen wir bestätigen, dass die Funktion zurückkehrt, ohne etwas zu tun.
Der zweite Test definiert wpJestTests
und verspottet die document.querySelector
zurückzugebende Methode, undefined
die zurückgegeben würde, wenn er kein Element im DOM finden könnte. In einem solchen Fall möchten wir bestätigen, dass wir zurückkommen, ohne etwas zu tun, und dass unsere Funktion mocking document.querySelector
einmal aufgerufen wurde.
Scheinabruf in Jest-Tests
Die nächste Testreihe beginnt mit
und darin haben wir eine weitere Teardown-Funktion:
Im Gegensatz afterEach
dazu wird ausgeführt, nachdem alle Tests in diesem describe
Block ausgeführt wurden. Da unsere JavaScript-Datei fetch
zum Laden der Posts verwendet wird, müssen wir überprüfen, ob sie aufgerufen wurde und das zurückgegeben hat, was wir angefordert haben, also werden wir die fetch
Funktion verspotten:
Wir verspotten das erste Promise, das in die Antwort aufgelöst wird, und das zweite in eine JSON-Darstellung der Daten. Diese Daten ähneln denen, die wir von der WP REST API erhalten. Da unser Code nur den Titel und den Link benötigt, machen wir uns darüber lustig.
JavaScript-Integrationstest mit Jest in asynchronem Code, der Fetch verwendet
Wir können jetzt den Test mit dem verspotteten schreiben fetch
. Bei diesem Test gibt es einen großen Unterschied zu den anderen JavaScript-Einheitentests: Es handelt sich um einen Integrationstest. Frühere Tests, die hier untersucht wurden, stellten einfach sicher, dass eine Komponente gut funktionierte. Wir haben überprüft, ob unsere Komponente nicht gerendert würde, wenn die globale Variable für den Anfangszustand nicht definiert wäre. Dies ist anders, weil wir testen werden, wie das gesamte System funktioniert, wenn die anfängliche Zustandsvariable definiert wird, wodurch eine Datentransaktion ausgelöst wird, und schließlich die Beitragstitel mit ihren Links in das Dokument eingefügt werden.
Das ist von vornherein anders: Die an übergebene anonyme Funktion test
erhält einen done
Parameter. Dies ist eigentlich eine Funktion, die aufgerufen wird, wenn wir den Test beenden. Jest wartet, bis done
er aufgerufen wird, bevor er den Test beendet. Wenn done
nie aufgerufen wird, schlägt der Test mit einem Zeitüberschreitungsfehler fehl. Das ist für uns interessant, da wir Code testen fetch
, der eine asynchrone Funktion enthält.
Das Global wpJestTests
ist definiert und unser Mocked document.querySelector
gibt jetzt etwas zurück, das einem HTML-Element ähnelt, mit even classList
und seiner add
untergeordneten Methode.
Wir rufen wpJestTestsInit
an und erwarten, dass es richtig endet. Da fetch
es asynchron ist, werden wir process.nextTick
von Node.js Gebrauch machen. Das nextTick
in Node.js ist die Warteschlange, die ausgeführt wird, nachdem alle Ereignisse in der aktuellen Ereignisschleife beendet wurden. Das ist großartig, weil dann alle unsere Versprechungen eingelöst würden, was genau das ist, was wir zum Testen dieses Codes brauchen, der fetch
.
Der Rest sind eher Behauptungen, um sicherzustellen querySelector
, dass etwas zum Arbeiten gefunden wurde, das fetch
tatsächlich aufgerufen wurde, dass eine Klasse zur Liste hinzugefügt wurde und dass die Titel und Links unserer Beiträge in das entsprechende HTML-Element eingefügt wurden. Sobald alles erledigt ist, rufen wir an done
und unser asynchroner Test endet.
Führen Sie Ihre Jest-Tests durch
Jetzt können Sie tippen
npm run test
und Jest führt die JavaScript-Einheitentests für Ihr WordPress-Plugin aus
Fazit
Jest ist also eine großartige und einfache Lösung, um Tests zu schreiben, die den JavaScript-Code unserer WordPress-Plugins oder -Themen abdecken. Aber es gibt noch mehr. Wenn wir eine React-App für unser Plugin schreiben, möchten wir vielleicht Behauptungen darüber aufstellen. Jest kann bis zu einem gewissen Grad auch helfen, und wenn wir mehr brauchen, können wir Enzyme zu unseren Tools hinzufügen und damit beginnen, Integrationstests zu schreiben.
Bitte spenden Sie!
Wenn Sie dies nützlich fanden, können Sie mir gerne einen Kaffee ausgeben , damit ich wach bleiben und weitere nützliche Tutorials für Sie erstellen kann!
$3.00