Test dei componenti in React Using Jest The Basics

Cosa starai creando

Il test del codice è una pratica confusa per molti sviluppatori. Ciò è comprensibile perché scrivere i test richiede più impegno, tempo e la capacità di prevedere possibili casi d'uso. Le startup e gli sviluppatori che lavorano su progetti più piccoli di solito preferiscono ignorare completamente i test a causa della mancanza di risorse e di risorse umane. 

Tuttavia, ci sono un paio di motivi per cui credo che dovresti testare i tuoi componenti:

  1. Ti fa sentire più sicuro del tuo codice.
  2. I test migliorano la tua produttività.

Reagire non è diverso neanche. Quando l'intera applicazione inizia a trasformarsi in una pila di componenti difficili da mantenere, il testing offre stabilità e coerenza. La scrittura dei test sin dal primo giorno ti aiuterà a scrivere codice migliore, a individuare i bug con facilità ea mantenere un flusso di lavoro di sviluppo migliore. 

In questo articolo, ti spiegherò tutto ciò che devi sapere per scrivere test per i tuoi componenti React. Tratterò anche alcune delle migliori pratiche e tecniche mentre ci siamo. Iniziamo!

Test dei componenti in React

Il test è il processo per verificare che il nostro asserzioni di prova sono veri e restano veri per tutta la vita dell'applicazione. Un'asserzione di test è un'espressione booleana che restituisce true a meno che non ci sia un bug nel codice. 

Ad esempio, un'affermazione potrebbe essere qualcosa di così semplice: "Quando l'utente naviga verso /accesso, un modale con l'id #accesso dovrebbe essere reso. "Quindi, se risulta che hai incasinato il componente di login in qualche modo, l'asserzione sarebbe tornata falsa. Le asserzioni non sono solo limitate a ciò che viene reso-puoi anche fare asserzioni su come l'applicazione risponde alle interazioni dell'utente e altre azioni. 

Esistono molte strategie di test automatizzate che gli sviluppatori front-end utilizzano per testare il loro codice. Limiteremo la discussione a soli tre paradigmi di test del software che sono popolari con React: test delle unità, test funzionali e test di integrazione.

Test unitario

Il test delle unità è uno dei veterani test che è ancora popolare nei circoli di test. Come suggerisce il nome, testerai singoli pezzi di codice per verificare che funzionino in modo indipendente come previsto. A causa dell'architettura dei componenti di React, i test unitari sono naturali. Sono anche più veloci perché non devi fare affidamento su un browser.

I test unitari ti aiutano a pensare a ciascun componente in isolamento ea trattarli come funzioni. Il tuo unit test per un particolare componente dovrebbe rispondere alle seguenti domande:

  1. Ci sono oggetti di scena? Se sì, cosa fa con loro?
  2. Quali componenti esegue il rendering? 
  3. Dovrebbe avere uno stato? Quando o come dovrebbe aggiornare lo stato?
  4. Esiste una procedura che dovrebbe seguire quando monta o smonta o sull'interazione dell'utente?

Test funzionali

I test funzionali vengono utilizzati per testare il comportamento di una parte della tua applicazione. I test funzionali sono generalmente scritti dal punto di vista dell'utente. Un pezzo di funzionalità non è in genere limitato a un singolo componente. Può essere una forma a tutti gli effetti o un'intera pagina. 

Ad esempio, quando si crea un modulo di registrazione, potrebbero essere coinvolti componenti per gli elementi del modulo, gli avvisi e eventuali errori. Anche il componente che viene visualizzato dopo che il modulo è stato inviato fa parte di tale funzionalità. Questo non richiede un renderer per browser perché useremo un DOM virtuale in memoria per i nostri test.

Test d'integrazione

Il test di integrazione è una strategia di test in cui tutti i singoli componenti vengono testati come gruppo. I test integrati tentano di replicare l'esperienza dell'utente eseguendo i test su un browser effettivo. Questo è considerevolmente più lento dei test funzionali e dei test unitari poiché ciascuna suite di test viene eseguita su un browser live. 

In React, i test unitari e i test funzionali sono più popolari dei test di integrazione perché sono più facili da scrivere e mantenere. Questo è ciò che tratteremo in questo tutorial.

Conosci i tuoi strumenti 

Sono necessari determinati strumenti e dipendenze per iniziare con il collaudo funzionale e unitario dell'applicazione React. Li ho elencati di seguito.

Jest Test Framework

Jest è un framework di test che richiede zero configurazioni ed è quindi facile da configurare. È più popolare dei framework di test come Jasmine e Mocha perché è sviluppato da Facebook. Jest è anche più veloce degli altri perché utilizza una tecnica intelligente per parallelizzare le esecuzioni dei test tra i lavoratori. A parte questo, ogni test viene eseguito in un ambiente sandbox in modo da evitare conflitti tra due test successivi. 

Se utilizzi l'app create-react, viene fornito con Jest. In caso contrario, potrebbe essere necessario installare Jest e alcune altre dipendenze. Puoi leggere maggiori informazioni sulla pagina di documentazione ufficiale di Jest. 

reagire-test-rendering

Anche se utilizzi l'app create-react, dovrai installare questo pacchetto per eseguire istantanee. Il test delle istantanee fa parte della libreria Jest. Pertanto, anziché eseguire il rendering dell'interfaccia utente dell'intera applicazione, è possibile utilizzare il renderer di test per generare rapidamente un output HTML serializzabile dal DOM virtuale. Puoi installarlo come segue:

filato aggiungere reattivo-renderer

ReactTestUtils and Enzyme

reagire-dom / test-utils consiste in alcune delle utility di test fornite dal team di React. In alternativa, puoi usare il pacchetto Enzyme rilasciato da Airbnb. Enzyme è molto meglio di ReactTestUtils perché è facile asserire, manipolare e attraversare l'output dei componenti di React. Inizieremo i nostri test con i programmi di utilità React e quindi passeremo a Enzyme in seguito.

Per installare Enzyme, eseguire il seguente comando.

filato aggiungere enzima-adattatore-reagire-16

Aggiungi il codice a src / SetupTests.js.

importare configure da 'enzyme'; adattatore di importazione da 'enzyme-adapter-react-16'; configure (adapter: new Adapter ());

Vi sono ulteriori informazioni a riguardo nella sezione Componenti di test della pagina di creazione-reazione-app. 

Impostazione di un'app demo e organizzazione dei test

Scriveremo dei test per una semplice applicazione demo che mostri una vista principale / dettagliata di un elenco di prodotti. Puoi trovare l'applicazione demo nel nostro repository GitHub. L'applicazione è costituita da un componente contenitore noto come ProductContainer e tre componenti di presentazione: ProductList, Dettagli del prodotto, e ProductHeader

Struttura della directory

. ├── package-lock.json ├── package.json ├── public │ ├── index.html │ └── manifest.json ├── src │ ├── componenti │ │ ├── App.js │ │ ├── ProductContainer.js │ │ ├── ProductDetails.jsx │ │ ├── ProductHeader.js │ │ ├── ProductList.jsx │ ├── index.js │ └── style.css

Questa demo è un buon candidato per test unitari e test funzionali. È possibile testare ciascun componente isolatamente e / o testare la funzionalità di elencazione del prodotto nel suo complesso. 

Dopo aver scaricato la demo, crea una directory con il nome __tests__dentro / src / componenti /. È quindi possibile memorizzare tutti i file di test relativi a questa funzionalità all'interno di __tests__ directory. I tester di solito nominano i loro file di test come entrambi .spec.js o .test.js-per esempio, ProductHeader.test.js o ProductHeader.spec.js

Scrivere test di base in React

Creare un ProductHeader.test.js file se non l'hai già fatto. Ecco come saranno sostanzialmente i nostri test:

src / componenti / __ test __ / ProductList.test.js

describe ('ProductHeader', () => it ('passing test', () => expect (true) .toBeTruthy ();) it ('failing test', () => expect (false) .toBeTruthy ();))

La suite di test inizia con a descrivere blocco, che è una funzione Jest globale che accetta due parametri. Il primo parametro è il titolo della suite di test e il secondo parametro è l'implementazione effettiva. Ogni esso () in una suite di test corrisponde a un test o una specifica. Un test contiene una o più aspettative che controllano lo stato del codice. 

si aspetta (vero) .toBeTruthy (); 

In Jest, un'aspettativa è un'affermazione che o restituisce vero o falso. Quando tutte le asserzioni in una specifica sono vere, si dice che passino. Altrimenti, si dice che il test fallisce.

Ad esempio, abbiamo creato due specifiche di prova. Il primo dovrebbe ovviamente passare, e il secondo dovrebbe fallire. 

Nota: toBeTruthy () è un matcher predefinito. In Jest, ogni matcher effettua un confronto tra il valore atteso e il valore effettivo e restituisce un valore booleano. Ci sono molti altri matchers disponibili e li daremo un'occhiata in un momento.

Esecuzione della Suite di test

create-react-app ha impostato tutto ciò che è necessario per eseguire la suite di test. Tutto ciò che devi fare è eseguire il seguente comando:

test del filato

Dovresti vedere qualcosa di simile a questo:

Per rendere superabile il test negativo, è necessario sostituire il toBeTruthy () matcher con toBeFalsy ().

attende (false) .toBeFalsy ();

Questo è tutto!

Utilizzo di Matchers in Jest

Come accennato in precedenza, Jest usa abbinamenti per confrontare i valori. Puoi usarlo per controllare l'uguaglianza, confrontare due numeri o stringhe e verificare la veridicità delle espressioni. Ecco l'elenco degli incontri più popolari disponibili su Jest. 

  • essere();
  • toBeNull ()
  • da definire()
  • toBeUndefined ()
  • toBeTruthy ()
  • toBeFalsy ()
  • toBeGreaterThan ()
  • toBeLesserThan ()
  • toMatch ()
  • contenere()

Questo è solo un assaggio. Puoi trovare tutti gli abbinamenti disponibili nei documenti di riferimento.

Test di un componente React

In primo luogo, scriveremo un paio di test per il ProductHeader componente. Apri il File ProductHeader.js se non l'hai già fatto. 

src / componenti / ProductHeader.js

import React, Component da 'react'; class ProductHeader estende Component render () return ( 

Pagina di elenco prodotti

); ; esportare ProductHeader predefinito;

Sei curioso di sapere perché ho usato un componente di classe qui invece di un componente funzionale? Il motivo è che è più difficile testare i componenti funzionali con ReactTestUtils. Se sei curioso di sapere perché, questa discussione sull'overflow dello stack ha la risposta.

Potremmo scrivere un test con le seguenti ipotesi:

  1. Il componente dovrebbe rendere un h2 etichetta.
  2. Il h2 il tag dovrebbe avere una classe chiamata titolo.

Per rendere un componente e recuperare nodi DOM rilevanti, abbiamo bisogno di ReactTestUtils. Rimuovi le specifiche fittizie e aggiungi il seguente codice:

src / componenti / __ test __ / ProductHeader.test.js

import Reagire da "reagire"; importare ReactTestUtils da 'react-dom / test-utils'; import Elenco prodotti da '... / ProductsList'; define ('ProductHeader Component', () => it ('ha un tag h2', () => // Test qui); it ('è racchiuso all'interno di una classe titolo', () => / / Test qui))

Per verificare l'esistenza di un h2 nodo, dovremo prima rendere i nostri elementi React in un nodo DOM nel documento. Puoi farlo con l'aiuto di alcune delle API esportate da ReactTestUtils. Ad esempio, per rendere il nostro componente, puoi fare qualcosa del genere:

 const component = ReactTestUtils.renderIntoDocument (); 

Quindi, puoi estrarre il h2 tag dal componente con l'aiuto di findRenderedDOMComponentWithTag ( 'tag-name'). Controlla tutti i nodi figlio e trova il nodo che corrisponde a tag-name

Ecco le specifiche del test completo.

 ('ha un tag h2', () => const component = ReactTestUtils.renderIntoDocument (); var h2 = ReactTestUtils.findRenderedDOMComponentWithTag (componente, 'h2'); );

Prova a salvarlo e il tuo test runner dovrebbe mostrarti che il test è passato. Questo è un po 'sorprendente perché non ne abbiamo uno aspettarsi() dichiarazione come nel nostro esempio precedente. La maggior parte dei metodi esportati da ReactTestUtils avere aspettative integrate in loro. In questo caso particolare, se l'utilità di test non riesce a trovare il h2 tag, genererà un errore e i test falliranno automaticamente.

Ora prova a creare il codice per il secondo test. Puoi usare findRenderedDOMcomponentWithClass () per verificare se c'è un nodo con il titolo della classe.

 ('has a title class', () => const component = ReactTestUtils.renderIntoDocument (); var node = ReactTestUtils.findRenderedDOMComponentWithClass (componente, 'titolo'); )

Questo è tutto! Se tutto va bene, dovresti vedere i risultati in verde. 

Conclusione

Anche se abbiamo appena scritto due specifiche di test, abbiamo coperto molti aspetti del processo. Nel prossimo articolo, scriveremo alcuni test completi per la nostra pagina di elenco dei prodotti. Sostituiremo anche ReactTestUtils con Enzyme. Perché? Enzyme offre un'interfaccia di alto livello che è molto facile da usare e sviluppatore-friendly. Restate sintonizzati per la seconda parte!

Se in qualsiasi momento ti senti bloccato o hai bisogno di aiuto, faccelo sapere nei commenti.