Ved hjelp av Cypress å Skrive Tester for en Reagerer Program

0
15

Ende-til-ende-tester er skrevet for å hevde flyten av et program fra start til slutt. I stedet for håndtering av tester deg selv — du vet, manuelt klikke hele programmet — du kan skrive en test som går som du bygger programmet. Det er hva vi kaller kontinuerlig integrasjon , og det er en vakker ting. Skrive noen kode, lagre det, og la verktøy gjøre det skitne arbeidet for å gjøre sikker på at det ikke ødelegge noe.

>Cypress ligger bare en ende-til-ende-testing rammeverk som gjør at du kan klikke jobbe for oss, og det er det vi skal se på i dette innlegget. Det er virkelig for alle moderne JavaScript-bibliotek, men vi kommer til å integrere den med Reagerer på eksempler.

La oss sette opp en app for å teste

I denne opplæringen, vil vi skrive tester for å dekke et todo-programmet jeg har bygget. Du kan klone depotet til å følge med når vi plugger i Cypress.

git clone [email protected]:kinsomicrote/cypress-reagere-opplæringen.git

Navigere i programmet og installere avhengigheter:

cd-cypress-reagere-opplæringen
garn installere

Cypress ikke er en del av avhengigheter, men du kan installere det ved å kjøre dette:

garn legge cypress –dev

Nå, kjør denne kommandoen for å åpne Cypress:

node_modules/.bin/cypress åpen

Å skrive at kommandoen til terminal over og over kan bli slitsomt, men du kan legge til dette skriptet til pakken.json-fil i prosjektet:root:

“cypress”: “cypress åpne”

Nå, alt du trenger å gjøre er å gjøre npm kjøre cypress gang og Cypress vil stå på med til alle tider. Å ha en følelse av hva programmet vi skal teste ser ut som, du kan starte Reagere programmet ved å kjøre garn start.

Vi vil begynne med å skrive en test for å bekrefte at Cypress fungerer. I cypress/integrering-mappen, kan du opprette en ny fil som heter init.spec.js. Testen hevder at sann er lik sant. Vi trenger den bare å bekrefte at arbeider for å sikre at Cypress, er oppe og kjører for hele programmet.

beskrive(‘Cypress’, () => {
det(‘arbeider’, () => {
forventer(sann).å.lik(sann)
})
})

Du bør ha en liste over tester åpne. Gå dit og velg init.spec.js.

Det bør føre til testen for å kjøre og dukker opp en skjerm som viser testen passerer.

Mens vi er fortsatt i init.spec.js la oss legge til en test for å hevde at vi kan besøke app ved å trykke http://localhost:3000 i nettleseren. Dette vil sørge for at selve appen kjører.

det(‘besøk app’, () => {
cy.besøk(‘http://localhost:3000’)
})

Vi kaller metoden besøk (), og vi passerer den URL-en til appen. Vi har tilgang til et globalt objekt kalt cy for å kalle metodene som er tilgjengelige for oss på Cypress.

For å unngå å måtte skrive URL-adressen gang på gang og vi kan sette en base-URL-er som kan brukes i hele tester vi skriver. Åpne cypress.json-fil i hjemmekatalogen av programmet og legge angi URL-er det:

{
“baseUrl”: “http://localhost:3000”
}

Du kan endre test blokk til å se ut som dette:

det(‘besøk app’, () => {
cy.besøk(‘/’)
})

…og testen bør fortsette å passere. 🤞

Testing form knapper og innganger

Testen vi skal skrive vil dekke hvordan brukerne samhandler med todo-programmet. For eksempel, vi ønsker å sikre at inngangen er i fokus når appen laster, slik at brukere kan begynne å skrive inn oppgaver umiddelbart. Vi ønsker også å sikre at det er en standard oppgave i det slik at listen ikke er tom som standard. Når det ikke er noen oppgaver vi ønsker å vise tekst som forteller brukeren så mye.

For å komme i gang, gå videre og opprette en ny fil i mappen integrasjon kalt form.spec.js. Navnet på filen er ikke så viktig. Vi er prepending “form”, fordi det vi er testing er til syvende og sist en form input. Du ønsker kanskje å kalle det noe annet, avhengig av hvordan du har tenkt på å organisere tester.

Vi kommer til å legge til en blokk for å beskrive filen:

beskrive(‘Form’, () => {
beforeEach(() => {
cy.besøk(‘/’)
})

det(‘den fokuserer input’, () => {
cy.fokusert().bør(‘have.class’, ‘skjema-control’)
})
})

Den beforeEach blokken brukes for å unngå unødvendige gjentakelser. For hver blokk av testen, må vi besøker programmet. Det ville være overflødig å gjenta denne linjen hver gang beforeEach sikrer Cypress besøk søknad i hvert enkelt tilfelle.

For test, la oss sjekke at DOM-element i fokus når programmet først laster har en klasse av form-kontroll. Hvis du vil kontrollere kilde filen, vil du se at input-elementet har en klasse kalt form-kontroll satt til det, og vi har autofokus som en av de element egenskaper:

<input
type=”text”
autofokus
value={dette.staten.elementet}
onChange={dette.handleInputChange}
plassholder=”skriv Inn en oppgave”
className=”form-kontroll”
/>

Når du lagrer det, gå tilbake til skjermen, og velg test form.spec.js for å kjøre test.

Det neste vi skal gjøre er å teste om en bruker kan lykkes med å angi en verdi i feltet.

det(‘aksepterer inndata’, () => {
const input = “Lære om Cypress”
cy.få(‘.form-control’)
.type(inngang)
.bør(‘har.verdi’, inngang)
})

Vi har lagt inn litt tekst (“Lære om Cypress”) til inngangen. Så vi gjør bruk av cy.får å få DOM-element med form-kontroll klasse navn. Vi kan også gjøre noe som cy.få(‘input’) og få samme resultat. Etter å ha fått element, cy.type() brukes til å angi verdien vi er tilordnet til inngangen, så vi hevde at DOM-element med klasse form-kontroll har en verdi som samsvarer med verdien av input.

Med andre ord:

Våre programmet bør også ha to todos som er opprettet ved standard når programmet kjører. Det er viktig at vi har en test som sjekker at de faktisk oppført.

Hva ønsker vi? I koden vår, vi gjør bruk av i listen (<li>) element for å vise oppgaver som elementer i en liste. Siden vi har to elementene som er oppført som standard, det betyr at listen bør ha en lengde på to på start. Så, testen vil se ut noe som dette:

det (“viser liste over todo’, () => {
cy.få(‘li’)
.bør(‘har.lengde’, 2)
})

Oh! Og hva vil dette programmet være hvis en bruker var i stand til å legge til en ny oppgave til listen? Vi bør teste at så godt.

det(‘legger til en ny todo’, () => {
const input = “Lære om cypress”
cy.få(‘.form-control’)
.type(inngang)
.type(‘{enter}’)
.få(‘li’)
.bør(‘har.lengde’, 3)
})

Dette ligner på det vi skrev i de to siste testene. Vi får innspill og simulere å skrive inn en verdi i det. Så, vi simulere sende inn en oppgave som bør oppdatere statusen til programmet, og dermed økt lengde fra 2 til 3. Så, egentlig, vi kan bygge ut av hva vi allerede har!

Endre verdien fra tre til to, vil føre til at test for å mislykkes — det er hva vi ville forvente, fordi listen skal ha to oppgaver som standard, og sende inn en gang skal produsere en sum av tre.

Du kanskje lurer på hva som ville skje hvis brukeren sletter enten (eller begge) av standard oppgaver før du forsøker å sende en ny oppgave. Vel, vi kunne skrive en test for det også, men vi er ikke slik at forutsetningen i dette eksemplet siden vi kun ønsker å bekrefte at oppgaver kan sendes inn. Dette er en enkel måte for oss å teste den grunnleggende sende inn funksjonalitet som vi utvikle og vi kan kontoen for avansert/edge saker senere.

Det siste har vi behov for å teste er å slette oppgaver. For det første, vi vil slette en av de standard oppgave elementer, og deretter se om det er en gjenværende når slettingen skjer. Det er samme slags avtale som før, men vi bør forvente ett element igjen i listen i stedet for de tre vi forventet når du legger til en ny oppgave på listen.

det(‘sletter en todo’, () => {
cy.få(‘li’)
.første()
.finn(‘.btn-fare”)
.klikk på()
.få(‘li’)
.bør(‘har.lengde’, 1)
})

OK, så hva skjer hvis vi sletter både av standard oppgaver i listen, og listen er helt tom? La oss si at vi ønsker å vise denne teksten når det ikke er flere elementer i listen: “Alle oppgaver er fullført. Pent gjort!”

Dette er ikke så forskjellig fra hva vi har gjort før. Du kan prøve det ut først for så å komme tilbake for å se koden for det.

det.bare(‘sletter alle todo’, () => {
cy.få(‘li’)
.første()
.finn(‘.btn-fare”)
.klikk på()
.få(‘li’)
.første()
.finn(‘.btn-fare”)
.klikk på()
.få(‘.ingen oppgave’)
.bør(‘har.tekst’, ‘Alle oppgaver er fullført. Pent gjort!’)
})

Begge testene ser like ut: vi får listen element for element, mål den første, og gjøre bruk av cy.finn() for å se etter DOM-element med en btn-fare klasse navn (som igjen er en helt vilkårlig klasse navn på slett-knappen i dette eksemplet app). Vi simulere et klikk hendelse på elementet for å slette oppgaven element.

Jeg ser etter “Ingen oppgave!” i akkurat denne testen.

Testing nettverksforespørsler

Nettverk forespørsler er slag av en stor avtale, fordi det er ofte kilden til data som brukes i en applikasjon. Si vi har en komponent i vår app som gjør en forespørsel til serveren for å få data som vil bli vist til brukeren. La oss si at komponenten markup ser ut som dette:

klasse App strekker seg til å Reagere.Komponent {
tilstand = {
isLoading: true,
brukere: [],
feil: null
};
fetchUsers() {
hente(`https://jsonplaceholder.typicode.com/users`)
.deretter(svar => svar.json())
.deretter(data =>
dette.setState({
brukere: data,
isLoading: false,
})
)
.catch(feil => dette.setState({ feil, isLoading: false }));
}
componentDidMount() {
dette.fetchUsers();
}
render() {
const { isLoading, brukere, feil } = dette.staten;
retur (
<Reagere.Fragment>
<h1>Tilfeldig Bruker</h1>
{feil ? <p>{feil.melding}</p> : null}
{!isLoading ? (
brukere.kart(user => {
const { brukernavn, navn, e } = user;
retur (
<div key={brukernavn}>
<p>Navn: {name}</p>
<p>E-post Adresse: {e}</p>
<hr />
</div>
);
})
) : (
<h3>Laster…</h3>
)}
</Reagere.Fragment>
);
}
}

Her gjør vi bruk av JSON Plassholder API som et eksempel. Kan vi ha en test som dette, for å teste responsen vi får fra serveren:

beskrive(‘Be’, () => {
det(‘viser tilfeldige brukere fra API’, () => {
cy.forespørsel(‘https://jsonplaceholder.typicode.com/users’)
.bør((respons) => {
forventer(respons.status).å.eq(200)
forventer(respons.kroppen).å.har.lengde(10)
forventer(respons).å.har.eiendom(‘hoder’)
forventer(respons).å.har.eiendom(‘varighet’)
})
})
})

Fordelen med å teste serveren (i motsetning til stubbing det) er at vi er sikker på at svaret vi får er den samme som den som en bruker vil få. For å lære mer om nettverk forespørsler og hvordan du kan spire nettverk forespørsler, se denne siden i Cypress dokumentasjon.

Kjører tester fra kommandolinjen

Cypress testene kan kjøres fra terminalen uten levert UI:

./node_modules/.bin/cypress run

…eller

npx cypress run

La oss kjøre form tester vi skrev:

npx cypress run –posten –spec “cypress/integration/form.spec.js”

Terminalen skal output resultater rett det med en oppsummering av hva som ble testet.

Det er en mye mer om bruk av Cypress med kommando linje i dokumentasjonen.

Det er en wrap!

Testene er noe som enten får folk opphisset eller redd, avhengig av hvem du snakker til. Forhåpentligvis hva vi har sett på i dette innlegget får alle spent på å implementere tester i et program, og viser hvor relativt enkelt det kan være. Sypress er et utmerket verktøy og en jeg har funnet meg selv nå for i mitt eget arbeid, men det finnes andre også. Uavhengig av hvilket verktøy du bruker (og hvordan du føler om tester), forhåpentligvis du se fordeler med testing og er mer tvunget til å gi dem en prøve.

Relaterte ressurser

  • Cypress: Du Skriver Ditt Første Test
  • GitHub: Cypress depotet
  • CSS-Triks: Komme i Gang med å Reagere Testing Bibliotek
  • CSS-Triks: Skriftlig Tester for å Reagere Programmer ved Hjelp av Spøk og Enzymet
  • CSS-Triks: Testing for Visual Regresjoner med Percy