Semplici unit test JavaScript in WordPress con Jest
WordPress ha una lunga esperienza di unit test del suo codice PHP. Tuttavia, la scrittura di unit test JavaScript e test di integrazione per il codice in temi e plugin non gode dello stesso stato. Vediamo come testare JavaScript nei nostri plugin e temi WordPress usando Jest.
Questi sono i contenuti che tratteremo in questo articolo:
Test unitari JavaScript in WordPress
Allora perché scrivere unit test e test di integrazione? Sono ottimi per garantire che una funzione, un metodo di classe o anche un componente React esegua ciò che dovrebbero fare. Aiuta a rilevare gli errori nel codice e aiuta anche a preservare l’integrità quando le modifiche vengono introdotte successivamente nel codice verificando che funzioni ancora come previsto dopo l’aggiornamento.
I plugin e i temi di WordPress sono per lo più scritti in PHP e possono utilizzare la suite PHPUnit per eseguire test, fare asserzioni, funzioni beffarde e altro ancora. Il manuale ha anche una sezione che spiega come impostare rapidamente i test delle unità con WP-CLI.
Per JavaScript, c’è una pagina sull’esecuzione dei test QUnit nel Manuale, anche se si tratta più di testare il codice JavaScript nel core di WordPress.
Sebbene nulla di tutto ciò sia standardizzato per JavaScript in WordPress, possiamo scrivere ottimi unit test utilizzando la suite di test Jest. In questo articolo impareremo come scrivere unit test JavaScript per un plug-in di esempio che carica 5 post tramite l’API REST di WP utilizzando la fetch
funzione di JavaScript e li rende in un determinato elemento DOM nella pagina.
Vantaggi dell’utilizzo di Jest per i test unitari JavaScript in WordPress
In passato, la scrittura di unit test JavaScript implicava l’impostazione di Mocha per eseguire test, Chai per fare asserzioni e Sinon per deridere le funzioni e spiarle. Sebbene offrano una grande flessibilità, è molto più complesso lavorare con tre pacchetti rispetto a uno. Jest fornisce tutto questo in un unico pacchetto:
- puoi eseguire dei test dichiarandoli con
describe
eit
otest
- puoi fare affermazioni con
expect
etoBe
,toHaveLength
e molti altri - puoi deridere le funzioni e spiarle, e ci sono diversi modi per farlo
Prima di andare avanti
Per mantenere questo articolo incentrato sui test con Jest, c’è una configurazione aggiuntiva esterna al processo di test come Babel o Webpack che non sarà trattata qui. Tutto questo può essere trovato nel repository WP Jest Tests che accompagna questo articolo. Per mantenere le cose contestuali, ogni sezione si collegherà a uno dei file rilevanti che scriveremo.
Panoramica del lato PHP
Il PHP per il plugin di esempio che useremo per imparare a scrivere gli unit test JavaScript è abbastanza standard. Le uniche righe interessanti sono quelle in cui accodiamo il nostro file JavaScript e aggiungiamo uno script inline per passarci variabili:
Dopo aver inserito il nostro file JavaScript, aggiungiamo una variabile globale wpJestTests
con wp_add_inline_script()
. Questa variabile è particolarmente interessante e difficile da gestire perché è esterna al nostro file JavaScript e dovremo prenderla in giro nei nostri test.
Imposta i test Jest
Dovremo prima inizializzare npm
nel nostro progetto di plugin per poter installare Jest con esso. Passare dalla riga di comando alla cartella del plug-in ed eseguire:
npm init
e segui la serie di prompt qui
Modifica il file package.json che è stato creato e aggiungi una nuova voce per eseguire i nostri test nella scripts
sezione:
"test": "jest"
Questo sarà il comando che useremo per dire a Jest di eseguire i nostri unit test JavaScript. Questa è una corsa una tantum, ma Jest supporta anche il monitoraggio dei file, quindi puoi inserirne uno aggiuntivo:
"test-watch": "jest --watch"
Ora installa Jest come dipendenza di sviluppo eseguendo
npm install -D jest
Durante l’installazione, crea un file denominato jest.config.js
. Questo manterrà tutta la configurazione necessaria. Aggiungi quanto segue:
module.exports = {
verbose: true,
setupFiles: [
'/__mocks__/globals.js'
],
moduleNameMapper: {
'.(css|less|sass|scss)$': '/__mocks__/styleMock.js'
}
};
Esaminiamo ciascuno di essi:
verbose
: indica se ogni singolo test deve essere riportato durante la corsa. Tutti gli errori verranno visualizzati anche in basso dopo l’esecuzione. Si noti che se viene eseguito un solo file di test, il valore predefinito ètrue
.setupFiles
: un elenco di percorsi di moduli che eseguono del codice per configurare o impostare l’ambiente di test. Ogni setupFile verrà eseguito una volta per file di test. Poiché ogni test viene eseguito nel proprio ambiente, questi script verranno eseguiti nell’ambiente di test immediatamente prima dell’esecuzione del codice di test stesso. Lo useremo per dichiarare le variabili globali rese da PHP e WordPress con comandi comewp_add_inline_script
owp_localize_script
.moduleNameMapper
: questa è una mappa da espressioni regolari a nomi di moduli (o array di nomi di moduli) che consentono di stubout risorse statiche, come immagini o stili con un singolo modulo.
Hai sicuramente notato il riferimento: questo è un token speciale che viene sostituito da Jest con la radice del tuo progetto, che di solito è la posizione del tuo package.json
.
Approfondiremo nelle prossime due sezioni, ma prima creiamo la cartella e questi due file a cui si fa riferimento sopra:
- creare una cartella denominata
__mocks__
- all’interno della cartella, creare i file
styleMock.js
eglobals.js
Importazione di stili fittizi per i test Jest
Se, come questo plugin, usi Webpack per compilare tutto, inclusi gli stili e stai importando il .scss
file nel .js
file:
import './main.scss';
è necessario utilizzare styleMock.js per deridere i file SASS durante l’importazione nel nostro file JavaScript, altrimenti Jest si arresterà in modo anomalo poiché non sarà in grado di risolvere il modulo. Non hai bisogno di molto per questo file, basta aggiungere
Jest utilizzerà questo mock ogni volta che trova .scss
un’importazione e li mapperà al mock, permettendoti di andare avanti con i test senza preoccuparti degli stili.
Imposta globali per Jest
Lavoriamo ora nel file globals.js. Uno dei vantaggi dell’utilizzo di Jest è che viene già fornito con un jsdom
, un’implementazione JavaScript puro degli standard Web già configurata, che simula un ambiente DOM come se fossi nel browser e lo useremo per deridere gli elementi DOM per i nostri test
Crea una cartella __mocks__
e un globals.js
file al suo interno. Aggiungi questo al file:
import { JSDOM } from 'jsdom';
const dom = new JSDOM();
global.document = dom.window.document;
global.window = dom.window;
global.window.wpJestTests = undefined;
Questo dichiarerà e deriderà alcuni oggetti e metodi che utilizzerai in seguito nei tuoi test. L’ultimo è di particolare interesse
global.window.wpJestTests = undefined;
Questa è la variabile globale che abbiamo scritto usando wp_add_inline_script
. Devi prenderlo in giro come una variabile globale per poterlo utilizzare nei tuoi test.
Panoramica del file JavaScript
Il plugin di WordPress ha un unico file JavaScript main.js in una /src
cartella. Questo viene successivamente traspilato e prodotto in un /js/front.js
file che è ciò che il PHP caricherà. Il JavaScript carica cinque post di WordPress utilizzando fetch
, una funzione JavaScript standard, tramite l’API REST di WP e inserisce il suo titolo, con un collegamento al post, in un file div.entry-content
.
Stai per esportare la funzione che fa tutto il lavoro:
quindi puoi usarlo nei tuoi test in Jest.
Scrivere test unitari JavaScript con Jest, finalmente!
Ora puoi iniziare a scrivere i test! Jest può trovare i test in molti modi:
- se il nome del file è
test.js
- o è preceduto dal nome del file che verifica, come
main.test.js
- se sono
.js
file che si trovano in una cartella denominata__tests__
Crea la __tests__
cartella e al suo interno, un file front.test.js
. Puoi vedere il file JavaScript finito per i test Jest nel repository complementare. Esaminiamolo a blocchi. La prima riga importa il file JS che vogliamo testare:
import { wpJestTestsInit } from '../src/main';
Successivamente, cancelliamo tutti i mock, quindi non corriamo mai con mock sporchi che trasportano i valori dei test precedenti. Ciò può portare a errori poiché, ad esempio, se stiamo spiando quante volte è stata chiamata una funzione presa in giro, potremmo ottenere una lettura errata se non cancelliamo la simulazione tra test e test:
Il primo test che scriveremo, fa affermazioni di base quando alcune cose falliscono. Ad esempio, se la variabile globale wpJestTests
con cui stavamo scrivendo wp_add_inline_script
non è stata scritta per nessun motivo:
In questo codice,
describe
crea un gruppo composto da diversi test correlatitest
è ciò che esegue effettivamente un testexpect
avvolge il nostro soggetto di test fornendo accesso a una serie di "corrispondenti" che ti consentono di fare affermazioni diverse sul suo contenutotoBe
è uno di questi abbinamenti. Jest ha molti abbinatori inclusi e ce ne sono anche altri che puoi aggiungere con un pacchetto di terze parti.
Il primo test non sta definendo nulla wpJestTests
, quindi il suo valore sarà quello che hai definito in globals.js
. Poiché è undefined
, non possiamo lavorare, quindi vogliamo confermare che la funzione ritorna senza fare nulla.
Il secondo test definisce wpJestTests
e prende in giro il document.querySelector
metodo da restituire undefined
che è ciò che restituirebbe se non riuscisse a trovare un elemento nel DOM. In tal caso, vogliamo confermare che stiamo tornando senza fare nulla e che la nostra funzione mocking document.querySelector
è stata chiamata una volta.
Recupero fittizio nei test di Jest
La prossima serie di test inizia con
e all’interno di questo, abbiamo un’altra funzione di smontaggio:
a differenza afterEach
di questo, verrà eseguito dopo che tutti i test all’interno di questo describe
blocco sono stati eseguiti. Poiché il nostro file JavaScript utilizza fetch
per caricare i post, dobbiamo verificare che sia stato chiamato e abbia restituito ciò che abbiamo richiesto, quindi prenderemo in giro la fetch
funzione:
Prendiamo in giro la prima Promise che risolve la risposta e la seconda una rappresentazione JSON dei dati. Questi dati sono simili a quelli che otteniamo dall’API REST di WP. Dato che il nostro codice ha bisogno solo del titolo e del collegamento, lo stiamo prendendo in giro.
Test di integrazione JavaScript con Jest in codice asincrono che utilizza fetch
Ora possiamo scrivere il test usando il mocked fetch
. C’è una grande differenza con questo test rispetto agli altri unit test JavaScript: questo è un test di integrazione. I test precedenti esaminati qui hanno semplicemente assicurato che un componente funzionasse bene. Abbiamo verificato che se la variabile globale dello stato iniziale non fosse stata definita, il nostro componente non sarebbe stato visualizzato. Questo è diverso perché testeremo come funziona l’intero sistema quando viene definita la variabile di stato iniziale, avviando così una transazione di dati e infine inserendo i titoli dei post con i relativi collegamenti nel documento.
Fin dall’inizio è diverso: la funzione anonima passata a test
riceve un done
parametro. Questa è in realtà una funzione che verrà chiamata al termine del test. Jest aspetterà fino a quando non done
verrà chiamato prima di terminare il test. Se done
non viene mai chiamato, il test fallirà con un errore di timeout. Questo è interessante per noi poiché stiamo testando il codice che coinvolge fetch
, che è una funzione asincrona.
Il globale wpJestTests
è definito e il nostro mocked document.querySelector
ora restituisce ciò che assomiglia a un elemento HTML, con anche classList
e il suo add
metodo figlio.
Chiamiamo wpJestTestsInit
e ci aspettiamo che finisca correttamente. Ora, poiché fetch
è asincrono, utilizzeremoprocess.nextTick
Node.js. In Node.js è la coda che verrà eseguita al termine di tutti gli eventi nel ciclo di eventi corrente. Questo è fantastico perché tutte le nostre promesse verrebbero risolte, che è esattamente ciò di cui abbiamo bisogno per testare questo codice che coinvolge .nextTick``fetch
Il resto sono altre affermazioni per garantire che sia stato querySelector
trovato qualcosa con cui lavorare, che fetch
sia stato effettivamente chiamato, che una classe sia stata aggiunta all’elenco e che i titoli e i collegamenti dei nostri post siano stati inseriti nell’elemento HTML corrispondente. Una volta fatto tutto, chiamiamo done
e il nostro test asincrono termina.
Esegui i tuoi test Jest
Ora puoi digitare
npm run test
e Jest eseguirà gli unit test JavaScript per il tuo plugin WordPress
Conclusione
Quindi Jest è un’ottima e semplice soluzione per scrivere test che coprono il codice JavaScript dei nostri plugin o temi WordPress. Ma c’è di più. Se stiamo scrivendo un’app React per il nostro plugin, potremmo voler fare delle affermazioni al riguardo. Anche Jest può aiutare fino a un certo punto e, se ne abbiamo bisogno di più, possiamo aggiungere Enzima ai nostri strumenti e iniziare a scrivere test di integrazione con esso.
Per favore dona!
Se l’hai trovato utile, sentiti libero di offrirmi un caffè così posso stare sveglio e creare tutorial più utili per te!
$ 3,00