Proste testy jednostkowe JavaScript w WordPressie z Jest
WordPress ma długą historię testów jednostkowych swojego kodu PHP. Jednak pisanie testów jednostkowych JavaScript i testów integracyjnych dla kodu w motywach i wtyczkach nie ma takiego samego statusu. Zobaczmy, jak przetestować JavaScript w naszych wtyczkach i motywach WordPress za pomocą Jest.
Oto treść, którą omówimy w tym artykule:
Testy jednostkowe JavaScript w WordPress
Po co więc pisać testy jednostkowe i testy integracyjne? Świetnie zapewniają, że funkcja, metoda klasy, a nawet komponent React robią to, co powinny. Pomaga wykrywać błędy w kodzie, a także pomaga zachować integralność, gdy zmiany zostaną później wprowadzone w kodzie, sprawdzając, czy po aktualizacji nadal działa zgodnie z przeznaczeniem.
Wtyczki i motywy WordPress są w większości napisane w PHP i mogą używać pakietu PHPUnit do przeprowadzania testów, tworzenia asercji, tworzenia funkcji i nie tylko. Podręcznik zawiera nawet sekcję wyjaśniającą, jak szybko skonfigurować testy jednostkowe za pomocą WP-CLI.
Jeśli chodzi o JavaScript, w Podręczniku znajduje się strona o uruchamianiu testów QUnit, chociaż bardziej chodzi o testowanie kodu JavaScript w rdzeniu WordPressa.
Chociaż żadna z tych rzeczy nie jest ustandaryzowana dla JavaScript w WordPress, możemy pisać świetne testy jednostkowe za pomocą zestawu testowego Jest. W tym artykule dowiemy się, jak pisać testy jednostkowe JavaScript dla przykładowej wtyczki, która ładuje 5 postów przez WP REST API za pomocą fetch
funkcji z JavaScript i renderuje je w określonym elemencie DOM na stronie.
Korzyści z używania Jest do testów jednostkowych JavaScript w WordPress
W przeszłości pisanie testów jednostkowych JavaScript wiązało się z konfiguracją Mocha do uruchamiania testów, Chai do tworzenia asercji, a Sinon do symulowania funkcji i ich szpiegowania. Chociaż oferują dużą elastyczność, praca z trzema pakietami jest znacznie bardziej skomplikowana niż z jednym. Jest to wszystko w jednym pakiecie:
- możesz uruchamiać testy deklarując je za pomocą
describe
iit
lubtest
- możesz dokonywać asercji za pomocą
expect
itoBe
itoHaveLength
wielu innych - możesz kpić z funkcji i je szpiegować, a jest na to wiele sposobów
Przed przejściem dalej
Aby ten artykuł koncentrował się na testowaniu za pomocą Jest, istnieje dodatkowa konfiguracja zewnętrzna w stosunku do procesu testowania, taka jak Babel lub Webpack, która nie zostanie tutaj omówiona. Wszystko to można znaleźć w repozytorium WP Jest Tests, które towarzyszy temu artykułowi. Aby zachować kontekst, każda sekcja będzie zawierać link do jednego z odpowiednich plików, które napiszemy.
Przegląd strony PHP
Przykładowa wtyczka PHP, której użyjemy do nauki pisania testów jednostkowych JavaScript, jest dość standardowa. Jedyne interesujące wiersze to te, w których umieszczamy w kolejce nasz plik JavaScript i dodajemy skrypt inline, który przekazuje do niego zmienne:
Po zaszyfrowaniu naszego pliku JavaScript dodajemy zmienną globalną wpJestTests
z wp_add_inline_script()
. Ta zmienna jest szczególnie interesująca i trudna w obsłudze, ponieważ jest zewnętrzna w stosunku do naszego pliku JavaScript i będziemy musieli ją wyśmiewać w naszych testach.
Skonfiguruj testy Jest
Najpierw musimy zainicjować npm
nasz projekt wtyczki, aby móc z nim zainstalować Jest. Przejdź w wierszu poleceń do folderu wtyczek i uruchom:
npm init
i przejdź przez serię podpowiedzi tutaj
Edytuj utworzony plik package.json i dodaj nowy wpis, aby uruchomić nasze testy w scripts
sekcji:
"test": "jest"
Będzie to polecenie, którego użyjemy, aby powiedzieć Jest, aby uruchomił nasze testy jednostkowe JavaScript. Jest to jednorazowe uruchomienie, ale Jest również obsługuje oglądanie plików, więc możesz wprowadzić dodatkowy:
"test-watch": "jest --watch"
Teraz zainstaluj Jest jako zależność programistyczną, uruchamiając
npm install -D jest
Podczas instalacji utwórz plik o nazwie jest.config.js
. To utrzyma całą niezbędną konfigurację. Dodaj następujące informacje:
module.exports = {
verbose: true,
setupFiles: [
'/__mocks__/globals.js'
],
moduleNameMapper: {
'.(css|less|sass|scss)$': '/__mocks__/styleMock.js'
}
};
Przyjrzyjmy się każdemu z nich:
verbose
: wskazuje, czy każdy indywidualny test powinien być raportowany podczas przebiegu. Po wykonaniu wszystkie błędy będą nadal wyświetlane na dole. Zauważ, że jeśli uruchomiony jest tylko jeden plik testowy, domyślnie jest totrue
.setupFiles
: lista ścieżek do modułów, które uruchamiają kod w celu skonfigurowania lub skonfigurowania środowiska testowego. Każdy plik setupFile zostanie uruchomiony raz na plik testowy. Ponieważ każdy test działa we własnym środowisku, skrypty te zostaną wykonane w środowisku testowym bezpośrednio przed wykonaniem samego kodu testowego. Użyjemy tego do deklarowania zmiennych globalnych renderowanych przez PHP i WordPress za pomocą poleceń takich jakwp_add_inline_script
lubwp_localize_script
.moduleNameMapper
: jest to mapa od wyrażeń regularnych do nazw modułów (lub tablic nazw modułów), która pozwala na zablokowanie zasobów statycznych, takich jak obrazy lub style za pomocą pojedynczego modułu.
Na pewno zauważyłeś odniesienie: jest to specjalny token, który jest zastępowany przez Jest z korzeniem twojego projektu, którym zwykle jest lokalizacja twojego package.json
.
Omówimy szczegółowo kolejne dwie sekcje, ale najpierw utwórz folder i te dwa pliki, o których mowa powyżej:
- utwórz folder o nazwie
__mocks__
- wewnątrz folderu utwórz pliki
styleMock.js
iglobals.js
Import mocków do testów Jest
Jeśli, tak jak ta wtyczka, używasz Webpacka do kompilacji wszystkiego, w tym stylów, i importujesz .scss
plik w .js
pliku:
import './main.scss';
musisz użyć styleMock.js, aby mockować pliki SASS podczas importowania ich do naszego pliku JavaScript, w przeciwnym razie Jest zawieszony, ponieważ nie będzie w stanie rozwiązać modułu. Nie potrzebujesz wiele do tego pliku, po prostu dodaj
Jest użyje tej makiety za każdym razem, gdy znajdzie .scss
import i zmapuje je do makiety, co pozwoli ci przejść do przodu z testami bez zwracania uwagi na style.
Skonfiguruj globalne dla Jest
Popracujmy teraz nad plikiem globals.js. Jedną z zalet używania Jest jest to, że jest już dostarczany z już skonfigurowaną jsdom
, implementacją standardów sieciowych w czystym języku JavaScript, która symuluje środowisko DOM tak, jakbyś był w przeglądarce, i użyjemy jej do symulowania elementów DOM do naszych testów.
Utwórz folder __mocks__
i globals.js
plik w nim. Dodaj to do pliku:
import { JSDOM } from 'jsdom';
const dom = new JSDOM();
global.document = dom.window.document;
global.window = dom.window;
global.window.wpJestTests = undefined;
Spowoduje to deklarację i mock niektórych obiektów i metod, których będziesz później używać w swoich testach. Szczególnie interesująca jest ta ostatnia
global.window.wpJestTests = undefined;
Jest to zmienna globalna, którą napisaliśmy za pomocą wp_add_inline_script
. Musisz zakpić ją jako zmienną globalną, aby móc używać jej w swoich testach.
Przegląd pliku JavaScript
Wtyczka WordPress zawiera pojedynczy plik JavaScript main.js w /src
folderze. Jest to później transpilowane i wyprowadzane do /js/front.js
pliku, który zostanie załadowany przez PHP. JavaScript ładuje pięć postów WordPress za fetch
pomocą standardowej funkcji JavaScript, za pośrednictwem interfejsu API WP REST i wstawia tytuł wraz z linkiem do posta do div.entry-content
.
Zamierzasz wyeksportować funkcję, która wykonuje całą pracę:
więc możesz go używać w swoich testach w Jest.
Nareszcie pisanie testów jednostkowych JavaScript za pomocą Jest!
Teraz możesz zacząć pisać testy! Testy można znaleźć na wiele sposobów:
- jeśli nazwa pliku to
test.js
- lub jest poprzedzony nazwą pliku, który testuje, na przykład
main.test.js
- jeśli są to
.js
pliki znajdujące się w folderze o nazwie__tests__
Utwórz __tests__
folder, a wewnątrz niego front.test.js
. Możesz zobaczyć gotowy plik JavaScript dla testów Jest w repozytorium towarzyszącym. Przejdźmy przez to blokami. Pierwsza linia importuje plik JS, który chcemy przetestować:
import { wpJestTestsInit } from '../src/main';
Następnie czyścimy wszystkie mocki, więc nigdy nie uruchamiamy brudnych mocków niosących wartości z poprzednich testów. Może to prowadzić do błędów, ponieważ na przykład, jeśli śledzimy, ile razy została wywołana funkcja, możemy uzyskać niepoprawny odczyt, jeśli nie wyczyścimy makiety między testem a testem:
Pierwszy test, który napiszemy, będzie zawierał podstawowe stwierdzenia, gdy pewne rzeczy zawiodą. Na przykład, jeśli wpJestTests
zmienna globalna, którą pisaliśmy, wp_add_inline_script
nie została zapisana z jakiegokolwiek powodu:
W tym kodzie
describe
tworzy grupę złożoną z kilku powiązanych ze sobą testówtest
jest tym, co faktycznie wykonuje testexpect
otacza nasz obiekt testowy, zapewniając dostęp do wielu „dopasowań", które pozwalają na wysuwanie różnych twierdzeń na temat jego zawartościtoBe
jest jednym z tych dopasowań. Jest zawiera wiele elementów dopasowujących, a nawet inne można dodać za pomocą pakietu innej firmy .
Pierwszy test niczego nie definiuje, wpJestTests
więc jego wartość będzie taka, jak zdefiniowałeś w globals.js
. Ponieważ jest to undefined
, nie możemy pracować, więc chcemy potwierdzić, że funkcja powraca bez robienia czegokolwiek.
Drugi test definiuje wpJestTests
i naśladuje document.querySelector
metodę, która ma zostać zwrócona undefined
, czyli to, co zwróciłaby, gdyby nie mogła znaleźć elementu w DOM. W takim przypadku chcemy potwierdzić, że wracamy bez robienia czegokolwiek i że nasza funkcja mocking document.querySelector
została wywołana raz.
Próbne pobieranie w testach Jest
Kolejny zestaw testów zaczyna się od
a wewnątrz mamy kolejną funkcję burzenia:
w przeciwieństwie do afterEach
tego zostanie uruchomione po wykonaniu wszystkich testów w tym describe
bloku. Ponieważ nasz plik JavaScript używa fetch
do ładowania postów, musimy sprawdzić, czy został wywołany i zwrócił to, o co prosiliśmy, więc zamierzamy zakpić fetch
funkcję:
Wyśmiewamy pierwszą obietnicę, która dotyczy odpowiedzi, a drugą reprezentację danych w formacie JSON. Te dane są podobne do tych, które otrzymujemy z API WP REST. Biorąc pod uwagę, że nasz kod potrzebuje tylko tytułu i linku, kpimy z tego.
Test integracji JavaScript z Jest w asynchronicznym kodzie, który używa fetch
Możemy teraz napisać test za pomocą mocked fetch
. Istnieje zasadnicza różnica między tym testem a innymi testami jednostkowymi JavaScript: jest to test integracyjny. Poprzednie testy, które tutaj omówiono, po prostu zapewniły, że komponent działa dobrze. Sprawdziliśmy, czy jeśli zmienna globalna stanu początkowego nie została zdefiniowana, nasz komponent nie będzie renderował się. Jest to inne, ponieważ zamierzamy przetestować działanie całego systemu, gdy zdefiniowana jest zmienna stanu początkowego, uruchamiając w ten sposób transakcję danych, a na koniec wstawiając tytuły postów wraz z linkami do dokumentu.
Od samego początku jest inaczej: funkcja anonimowa przekazana do test
otrzymuje done
parametr. W rzeczywistości jest to funkcja, która zostanie wywołana po zakończeniu testu. Jest czeka done
na wywołanie przed zakończeniem testu. Jeśli done
nigdy nie zostanie wywołany, test zakończy się niepowodzeniem z błędem przekroczenia limitu czasu. Jest to dla nas interesujące, ponieważ testujemy kod z udziałem fetch
funkcji asynchronicznej.
Globalny wpJestTests
jest zdefiniowany, a nasz mocked document.querySelector
teraz zwraca coś, co przypomina element HTML, z parzystą classList
i jego add
metodą potomną.
Wzywamy wpJestTestsInit
i oczekujemy, że zakończy się to poprawnie. Teraz, ponieważ jest fetch
asynchroniczny, użyjemy Node.js. In Node.js to kolejka, która zostanie uruchomiona po zakończeniu wszystkich zdarzeń w bieżącej pętli zdarzeń. To świetnie, ponieważ wszystkie nasze obietnice zostałyby wtedy rozwiązane, co jest dokładnie tym, czego potrzebujemy do testowania tego kodu, który obejmuje .process.nextTick
nextTick``fetch
Reszta to więcej asercji, aby upewnić się, że querySelector
znaleziono coś do pracy, co fetch
rzeczywiście zostało wywołane, że klasa została dodana do listy, a tytuły i linki naszych postów zostały wstawione w odpowiednim elemencie HTML. Gdy wszystko jest zrobione, wywołujemy done
i kończymy nasz test asynchroniczny.
Uruchom testy Jest
Teraz możesz pisać
npm run test
a Jest uruchomi testy jednostkowe JavaScript dla Twojej wtyczki WordPress
Wniosek
So Jest to świetne i proste rozwiązanie do pisania testów, które obejmują kod JavaScript naszych wtyczek lub motywów WordPress. Ale jest więcej. Jeśli piszemy aplikację React dla naszej wtyczki, być może zechcemy dokonać asercji na jej temat. Jest też do pewnego stopnia pomóc, a jeśli potrzebujemy więcej, możemy dodać Enzyme do naszych narzędzi i zacząć pisać z nim testy integracyjne.
Proszę podaruj!
Jeśli uznałeś to za przydatne, kup mi kawę , abym mógł nie zasnąć i stworzyć dla Ciebie więcej przydatnych samouczków!
3,00 zł