Det har blitt skrevet mye bra om enhetstesting av React-komponenter og Redux-reduksjonsverktøy med flere, men vi hadde store problemer med å finne fyldige innlegg om å sette opp skikkelige fullstack-integrasjonstester for den moderne JS-stakken.
Dette er artikkel 1 i en serie på 4 deler:
- Nightwatch og API-kall for rene, tette og isolerte fullstack-tester
- Gulp, AWS og Terraform for uanstrengt kontinuerlig levering
- Circle CI og Saucelabs for å automatisere alt
Oppsettet vårt var spesielt vanskelig fordi vi har en håndfull fullstendig frakoblede backend-tjenester og to React-apper som deler mye kode. Hvis du skal ned samme vei, sparer denne serien deg forhåpentligvis et par steg.
Nightwatch og API-kall for rene, tette og isolerte fullstack-tester
Målet er å skrive et sett med tester som faktisk trykktester hvordan frontend-appene og backend-tjenestene fungerer sammen. Dessuten, siden vi har brukere over hele verden som bruker Chrome, Firefox og IE på Windows og Mac, ønsker vi å være sikre på at vi ikke bryter sammen på noen kombinasjon av nettleser, operativsystem og skjermstørrelse vi forplikter oss til å støtte.
Her er en forhåndsvisning av feilsøking av hva vi utfører via CI ved hver push til Github, hver gren:
Viktig merknad: Testene ovenfor kjører uten mocks. Alle backend-tjenester er tilgjengelige for disse testene.
Felle A: Jeg har ofte sett fullstack-"røyktester" skrevet for Phantom- eller Selenium-wrappere som kjører en lang kjede med kommandoer i serie, der hver bygger på den forrige, logger inn og deretter går gjennom omfanget av en applikasjons funksjoner for å sikre at alt fungerer. Hver gang du trenger å endre eller legge til noe, ødelegger det noe nedstrøms. Nei takk.
Felle B: På samme måte har jeg sett ingeniører bygge makroer av forskjellige slag som utfører vanlige handlinger, og disse handlingene utføres deretter gjentatte ganger i nettleseren for å opprette vanlige tilstander. Effektivt, men tregt, spesielt hvis disse trinnene involverer mye brukergrensesnitt.
Denne gangen unngikk vi begge problemene ved å bruke API-verktøy for å sette opp tester nøyaktig slik vi trengte dem:
Det finnes et par nyttige triks begravd i disse innledende løftene. helpers.createTeam bruker API-et vårt til å opprette et nytt team og en ny bruker (hatt tips til faker.js), og bruker deretter den genererte legitimasjonen til å logge inn med Nightwatch ...
...og deretter separat for å hente et API-token som det kan bruke til påfølgende forespørsler:
Den enkle assign() -funksjonen lagrer de returnerte objektene for senere bruk.
Dette betyr at vi for hver eneste testblokk oppretter et nytt team og en ny bruker, i tillegg til alle dataobjektene vi trenger til testene. Virker overdrevent, bortsett fra at vi nå har automatiserte tester vi kan være sikre på er isolerte ... og dette betyr også at de kan kjøres parallelt . Mer om det kommer.
Justering av Nightwatch-sideobjekter med React Router
Nightwatch Page Objects implementerer en idé Martin Fowler foreslo her , om at du kan skille koden som kobler seg til en gitt side fra testene som verifiserer funksjonaliteten.
Vi har funnet ut at dette er enormt viktig for gjenbruk av testkode, og det hjelper oss å tenke logisk om funksjonaliteten vi bygger, spesielt for ikke-trivielle funksjoner.
Fordelen er spesielt tydelig når man gjennomgår en tyngre pull-forespørsel. Med et blikk er det ganske tydelig hva som skjer:
Deretter kan du se sideobjektet for å få en følelse av hvordan vi bruker brukergrensesnittet for å oppnå det testene ber om:
Du legger kanskje merke til at det å arkivere en mal krever at du godtar en SweetAlert -bekreftelsesdialogboks. Vi har konsepter som modaler og sweetAlert fanget som egne Nightwatch-sideobjekter, så det er enkelt å ta hensyn til dette trinnet, og siden det er innebygd i kommandoen på sideobjektet, trenger ikke testen å vite at en bekreftelse er nødvendig.
Når du er ferdig med å gjennomgå testene og sideobjektene, er det et lite hopp til å se React-komponentene som implementerer sideobjektet og Redux/Thrift-maskineriet som håndterer det React-komponentene trenger. Hvis du noen gang har opplevd at øynene dine er tåkete når du prøver å konsumere en større PR, tro meg, dette er et utrolig skritt fremover.
Siden React Router gir oss en så tydelig oversikt over nettstedskartet vårt, kan vi sørge for at sideobjektene forblir synkroniserte med rutene våre for begge appene, og så er vi klare.
Oppgrader Nightwatch med elektroverktøy som dra-og-slipp
NightwatchJS er en Selenium-wrapper som gir deg det meste av UI-navigasjonsfunksjonaliteten vi trenger, rett ut av esken. Men de lar deg også injisere skript for å forbedre testkapasiteten din.
I appen vår bruker vi i stor grad Dan Abramovs fantastiske React DnD- bibliotek. For å teste det satte Aaron opp en Nightwatch-kommando som pakker inn Andy Wermkes Drag Mock slik:
Dette lar oss inkludere dra-handlinger på sideobjekter:
Som gir oss en enkel og semantisk måte å definere drag-atferd i tester:
Akkurat som bruk av JSX har åpnet døren for at designerne våre kan sende inn flere design-PR-er, lar disse testteknikkene oss hente inn ganske yngre QA-automatiseringsingeniører til å hjelpe oss med å skrive tester av høy kvalitet, og manuelle QA-testere i teamet kan identifisere feiltolkninger av krav tidlig i prosessen. Alle vinner.
Rollen til fullstack-integrasjonstester
Merk at ingen av disse teknikkene fjerner behovet for solide enheter. Vi bruker Mocha til å teste Redux-reduksjonsverktøy/handlinger/osv., og vi bruker Enzyme til å teste React-komponenter isolert. Vi stryker også i en testkjøring hvis kildekoden ikke består ESLint.
Men jeg verdsetter disse fullstack-testene mye mer, fordi de bekrefter for oss at når vi fjerner mocks og kobler til alle backend-tjenestene, har vi fortsatt all funksjonaliteten vi lover brukerne våre, og ikke bare i Chrome på en Cinema Display i Soma, men også i praksis på en ødelagt Vista-bærbar PC som kjører IE11 på en oljeplattform. Det er der programvaren vår må levere, og Nightwatch gir oss trygghet om at vi er der.











