Testing av komponenter i React using Jest Grunderna

Vad du ska skapa

Testkod är en förvirrande övning för många utvecklare. Det är förståeligt eftersom skrivprov kräver mer ansträngning, tid och förmåga att förutse möjliga användningsfall. Startups och utvecklare som arbetar med mindre projekt favoriserar vanligtvis ignorerande test helt och hållet på grund av brist på resurser och arbetskraft. 

Det finns dock ett par anledningar till varför jag tror att du ska testa dina komponenter:

  1. Det gör att du känner dig mer säker på din kod.
  2. Tester förbättrar din produktivitet.

React är inte heller annorlunda. När hela applikationen börjar bli en stapel av komponenter som är svåra att bibehålla, erbjuder testning stabilitet och konsistens. Skrivprov från dag ett hjälper dig att skriva bättre kod, upptäcka buggar med lätthet och upprätthålla ett bättre utvecklingsarbete. 

I den här artikeln tar jag igenom allt du behöver veta för att skriva test för dina React-komponenter. Jag kommer också att täcka några av de bästa metoderna och teknikerna när vi är på det. Låt oss börja!

Testning av komponenter i reaktion

Test är processen att verifiera att vår test påståenden är sanna och att de är sanna under hela ansökans livstid. En testpåstående är ett booleskt uttryck som returnerar sant om det inte finns något fel i din kod. 

Till exempel kan en påstående vara så enkelt som detta: "När användaren navigerar till /logga in, en modal med id #logga in skulle bli gjord. "Så om det visar sig att du förstörde inloggningskomponenten på något sätt, skulle påståendet återvända falskt. Påståenden är inte bara begränsade till vad som görs - du kan också göra påståenden om hur ansökan svarar på användarinteraktioner och andra handlingar. 

Det finns många automatiserade teststrategier som front-end-utvecklare använder för att testa sin kod. Vi kommer att begränsa vår diskussion till bara tre programvaru testparadigmer som är populära med React: enhetstestning, funktionstestning och integrationstestning.

Enhetstestning

Enhetstester är en av testveteraner som fortfarande är populära i testcyklar. Som namnet antyder kommer du att testa enskilda kodstycken för att verifiera att de fungerar oberoende som förväntat. På grund av Reacts komponentarkitektur är enhetstesterna en naturlig passform. De är också snabbare eftersom du inte behöver lita på en webbläsare.

Enhetstester hjälper dig att tänka på varje komponent i isolation och behandla dem som funktioner. Din enhetstest för en viss komponent ska svara på följande frågor:

  1. Finns det några rekvisita? Om ja, vad gör det med dem?
  2. Vilka komponenter gör det? 
  3. Ska det ha en stat? När eller hur ska det uppdatera staten?
  4. Finns det ett förfarande som det ska följa när det monteras eller avmonteras eller om användarens interaktion?

Funktionstestning

Funktionella test används för att testa beteendet hos en del av din ansökan. Funktionstester skrivs vanligtvis ur användarens perspektiv. En del funktionalitet är vanligtvis inte begränsad till en enda komponent. Det kan vara en fullvärdig form eller en hel sida. 

När du till exempel bygger en registreringsblankett kan det innebära komponenter för formulärelementen, varningarna och eventuella fel. Den komponent som återges efter formuläret skickas också till den funktionen. Det här kräver inte en webbläsareåtergivare eftersom vi använder en virtuell DOM i minnet för våra test.

Integrationstestning

Integrationstestning är en teststrategi där alla enskilda komponenter testas som en grupp. Integrerad test försöker replikera användarupplevelsen genom att köra testen på en faktisk webbläsare. Detta är betydligt långsammare än funktionstester och enhetstest eftersom varje testpaket körs på en levande webbläsare. 

I React är enhetstester och funktionstester mer populära än integrationstest eftersom de är enklare att skriva och underhålla. Det är vad vi kommer att täcka i denna handledning.

Känn dina verktyg 

Du behöver vissa verktyg och beroenden för att komma igång med enhet och funktionstestning av din React-applikation. Jag har listat dem nedan.

Jest Test Framework

Jest är ett testramverk som kräver nollkonfiguration och är därför lätt att installera. Det är mer populärt än testramar som Jasmine och Mocha eftersom det är utvecklat av Facebook. Jest är också snabbare än resten eftersom det använder en smart teknik för att parallellisera testkörningar över arbetstagare. Bortsett från detta kör varje test i en sandlåda miljö för att undvika konflikter mellan två på varandra följande test. 

Om du använder skapa-reagera-app, levereras den med Jest. Om inte, kan du behöva installera Jest och några andra beroenden. Du kan läsa mer om det på den officiella dokumentationen för Jest dokumentation. 

reagerar-testet-renderare

Även om du använder skapa-reagera-app måste du installera det här paketet för att göra snapshots. Snapshot-test är en del av Jest-biblioteket. Så, istället för att göra användargränssnittet till hela applikationen, kan du använda teståtergivaren för att snabbt skapa en serialiserad HTML-utmatning från den virtuella DOM. Du kan installera det enligt följande:

garn lägg till reagens-test-renderer

ReactTestUtils och Enzyme

reagerar-DOM / testet-utils består av några av de testverktyg som tillhandahålls av React-teamet. Alternativt kan du använda paketet Enzyme som släppts av Airbnb. Enzym är mycket bättre än ReactTestUtils eftersom det är lätt att hävda, manipulera och spåra dina reaktorkomponenter. Vi kommer att starta våra tester med React utils och sedan övergå till Enzyme senare.

För att installera Enzym, kör följande kommando.

garn tillägg enzym enzym-adapter-reagera-16

Lägg till koden till src / SetupTests.js.

importera configure från "enzym"; Importadapter från "enzym-adapter-reagera-16"; konfigurera (adapter: ny adapter ());

Det finns mer information om detta i avsnittet Testkomponenter på sidan Skapa skapa-reagera. 

Installera en Demo App och organisera test

Vi kommer att skriva test för en enkel demo applikation som visar en mall / detaljvy av en lista över produkter. Du kan hitta demo-applikationen i vår GitHub repo. Ansökan består av en behållarkomponent som kallas ProductContainer och tre presentationsdelar: Produktlista, Produktinformation, och ProductHeader

Katalogstruktur

. ├── package-lock.json ├── package.json ├── public │ ├──index.html │ └── manifest.json ├── src │ ├── komponenter │ │ ├── App.js │ Produktkatalog

Denna demo är en bra kandidat för enhetstestning och funktionstestning. Du kan testa varje komponent isolerat och / eller testa produktlistans funktionalitet som helhet. 

När du har laddat ner demoen skapar du en katalog med namnet __tests__inuti / src / komponenter /. Du kan sedan lagra alla testfiler relaterade till denna funktionalitet i __tests__ katalogen. Testare brukar namnge sina testfiler som antingen .spec.js eller .test.js-till exempel, ProductHeader.test.js eller ProductHeader.spec.js

Skriva grundläggande test i React

Skapa en ProductHeader.test.js fil om du inte redan har det. Här är vad våra test i grund och botten kommer att se ut:

src / komponenter / __ tester __ / ProductList.test.js

beskriv ('ProductHeader', () => it ('pass test', () => förvänta (true) .toBeTruthy ();) it ('failing test' .toBeTruthy ();))

Testpaketet börjar med a beskriva block, vilket är en global Jest-funktion som accepterar två parametrar. Den första parametern är titeln på testpaketet och den andra parametern är den faktiska implementeringen. Varje Det() i en testpaket motsvarar ett test eller en spec. Ett test innehåller en eller flera förväntningar som kontrollerar koden. 

förväntar (sant) .toBeTruthy (); 

I Jest är en förväntan ett påstående som antingen returnerar sant eller falskt. När alla påståenden i en spec är sanna, sägs det övergå. Annars sägs testet misslyckas.

Vi har till exempel skapat två testspecifikationer. Den första ska självklart gå och den andra ska misslyckas. 

Notera: toBeTruthy () är en fördefinierad matchare. I Jest gör varje matchare en jämförelse mellan det förväntade värdet och det faktiska värdet och returnerar en booleska. Det finns många fler matchare tillgängliga, och vi tar en titt på dem på ett ögonblick.

Kör testpaketet

skapa-reagera-app har skapat allt som du behöver för att utföra testpaketet. Allt du behöver göra är att köra följande kommando:

garntest

Du borde se något så här:

För att göra det misslyckade testet måste du ersätta toBeTruthy () matcher med toBeFalsy ().

förväntar (false) .toBeFalsy ();

Det är allt!

Använda Matchers in Jest

Som tidigare nämnts använder Jest matchare för att jämföra värden. Du kan använda den för att kontrollera jämlikhet, jämföra två siffror eller strängar och verifiera truthiness av uttryck. Här är listan över populära matchare som finns i Jest. 

  • att vara();
  • toBeNull ()
  • att definieras()
  • toBeUndefined ()
  • toBeTruthy ()
  • toBeFalsy ()
  • toBeGreaterThan ()
  • toBeLesserThan ()
  • att matcha()
  • att innehålla()

Det här är bara en smak. Du hittar alla tillgängliga matchare i referensdokumenten.

Test av en reaktorkomponent

Först ska vi skriva ett par tester för ProductHeader komponent. Öppna upp ProductHeader.js-filen om du inte redan har det. 

src / komponenter / ProductHeader.js

Importreakt, Komponent från "reagera"; klass ProductHeader utökar komponent render () return ( 

Produktlista

); ; exportera standard ProductHeader;

Är du nyfiken på varför jag använde en klasskomponent här istället för en funktionell komponent? Anledningen är att det är svårare att testa funktionella komponenter med ReactTestUtils. Om du är nyfiken på varför har denna Stack Overflow-diskussion svaret.

Vi kunde skriva ett test med följande antaganden:

  1. Komponenten ska göra en h2 märka.
  2. De h2 tagg ska ha en klass som heter titel.

För att göra en komponent och att hämta relevanta DOM-noder behöver vi ReactTestUtils. Ta bort dummy-specifikationerna och lägg till följande kod:

src / komponenter / __ tester __ / ProductHeader.test.js

Import Reakt från "reagera"; Importera ReactTestUtils från "React-dom / test-utils"; importera ProductsList från '... / ProductsList'; beskriva ('ProductHeader Component', () => it ('har en h2 tag', () => // Test här); / Test här))

Att kontrollera om en h2 nod måste vi först göra våra React-element till en DOM-nod i dokumentet. Du kan göra det med hjälp av några av de API som exporteras av ReactTestUtils. Till exempel, för att göra vår komponent kan du göra något så här:

 const komponent = ReactTestUtils.renderIntoDocument (); 

Då kan du extrahera h2 tagg från komponenten med hjälp av findRenderedDOMComponentWithTag ( 'tagg-namn'). Det kontrollerar alla barnnoder och hittar noden som matchar taggnamn

Här är hela testspecifikationen.

 det ('har en h2-tag', () => const component = ReactTestUtils.renderIntoDocument (); var h2 = ReactTestUtils.findRenderedDOMComponentWithTag (komponent, 'h2'); );

Prova att spara det, och din testrunner ska visa dig att testet har passerat. Det är lite överraskande eftersom vi inte har någon förvänta() uttalande som i vårt tidigare exempel. De flesta metoder som exporteras av ReactTestUtils har förväntningar inbyggda i dem. I det här fallet, om testverktyget misslyckas med att hitta h2 taggen, det kommer att kasta ett fel och testen kommer automatiskt att misslyckas.

Försök nu skapa koden för det andra testet. Du kan använda findRenderedDOMcomponentWithClass () för att kontrollera om det finns någon nod med klassens titel.

 det ("har en titel klass", () => const component = ReactTestUtils.renderIntoDocument (); var node = ReactTestUtils.findRenderedDOMComponentWithClass (komponent, "titel"); )

Det är allt! Om allt går bra bör du se resultaten i grönt. 

Slutsats

Även om vi bara skrev två testspecifikationer, har vi täckt mycket av marken i processen. I nästa artikel skriver vi några fullfjädrade tester för vår produktnoteringssida. Vi ersätter också ReactTestUtils med Enzyme. Varför? Enzyme erbjuder ett gränssnitt på hög nivå som är väldigt lätt att använda och utvecklarvänligt. Håll dig klar för den andra delen!

Om du vid något tillfälle känner dig fast eller behöver hjälp, låt oss veta i kommentarerna.