En omfattende guide til Cypress, den kraftfulde end-to-end-testramme, der dækker installation, skrivning af tests, debugging, CI/CD-integration og bedste praksis.
Cypress: Den Ultimative End-to-End-Testningsguide til Webapplikationer
I nutidens hurtigt udviklende webudviklingslandskab er det altafgørende at sikre kvaliteten og pålideligheden af webapplikationer. End-to-End (E2E)-testning spiller en afgørende rolle i at verificere, at alle komponenter i en applikation fungerer problemfrit sammen fra brugerens perspektiv. Cypress er dukket op som en førende E2E-testramme, der tilbyder en udviklervenlig oplevelse, kraftfulde funktioner og fremragende ydeevne. Denne omfattende guide vil føre dig gennem alt, hvad du behøver at vide for at komme i gang med Cypress og effektivt teste dine webapplikationer.
Hvad er Cypress?
Cypress er et næste generations front-end testværktøj bygget til det moderne web. I modsætning til traditionelle testrammer, der kører tests i en browser, opererer Cypress direkte i browseren, hvilket giver dig enestående kontrol og synlighed over din applikations adfærd. Det er designet til at være hurtigt, pålideligt og nemt at bruge, hvilket gør det til et populært valg blandt udviklere og QA-ingeniører verden over. Cypress er skrevet i JavaScript og udføres i browseren, hvilket gør det meget performant og tilbyder enestående adgang til applikationens indre.
Vigtigste fordele ved at bruge Cypress
- Udvikler-venlig: Cypress leverer en ren og intuitiv API, hvilket gør det nemt at skrive og debugge tests.
- Tidsrejse: Cypress tager snapshots af din applikations tilstand under hver testkommando, så du kan gå tilbage i tiden og se præcis, hvad der skete på ethvert tidspunkt.
- Real-Time Reloads: Cypress genindlæses automatisk, når du foretager ændringer i dine tests, hvilket giver øjeblikkelig feedback.
- Automatisk Ventning: Cypress venter automatisk på, at elementer bliver synlige eller interaktive, før handlinger udføres, hvilket eliminerer behovet for eksplicitte waits.
- Netværkskontrol: Cypress giver dig mulighed for at stumpe netværksanmodninger og -svar, så du kan simulere forskellige scenarier og teste din applikations fejlhåndtering.
- Debugging: Cypress tilbyder fremragende debugging-værktøjer, herunder en kraftfuld debugger og detaljerede fejlmeddelelser.
- Cross-Browser Testing: Cypress understøtter flere browsere, herunder Chrome, Firefox, Edge og Electron.
- Headless Testing: Kør tests i headless mode for hurtigere udførelse i CI/CD-miljøer.
- Indbyggede påstande: Cypress tilbyder et rigt sæt af indbyggede påstande for at verificere den forventede adfærd af din applikation.
Installation og Opsætning
At komme i gang med Cypress er ligetil. Sådan installeres det:
- Forudsætninger: Sørg for, at du har Node.js og npm (Node Package Manager) installeret på dit system. Du kan downloade dem fra det officielle Node.js-websted.
- Installer Cypress: Åbn din terminal eller kommandoprompt, naviger til din projektmappe, og kør følgende kommando:
- Åbn Cypress: Når installationen er fuldført, kan du åbne Cypress Test Runner ved at køre:
npm install cypress --save-dev
npx cypress open
Denne kommando starter Cypress Test Runner, som giver en grafisk grænseflade til at køre og debugge dine tests.
Skrivning af din første Cypress-test
Lad os oprette en simpel test for at verificere, at en hjemmesides hjemmeside indlæses korrekt. Opret en ny fil med navnet `example.cy.js` i mappen `cypress/e2e` i dit projekt.
// cypress/e2e/example.cy.js
describe('Min første test', () => {
it('Besøger Kitchen Sink', () => {
cy.visit('https://example.cypress.io')
cy.contains('type').click()
cy.url().should('include', '/commands/actions')
cy.get('.action-email')
.type('fake@email.com')
.should('have.value', 'fake@email.com')
})
})
Lad os opdele denne test:
- `describe()`: Definerer en testsuite, som er en samling af relaterede tests.
- `it()`: Definerer en individuel testcase inden for testsuiten.
- `cy.visit()`: Navigerer til den angivne URL.
- `cy.contains()`: Finder et element, der indeholder den angivne tekst.
- `.click()`: Klikker på det valgte element.
- `cy.url()`: Henter den aktuelle URL på siden.
- `.should()`: Laver en påstand om applikationens tilstand.
- `cy.get()`: Vælger et element ved hjælp af en CSS-vælger.
- `.type()`: Indtaster tekst i det valgte element.
- `.should('have.value', 'fake@email.com')`: Påstår, at elementets værdi er lig med 'fake@email.com'.
Kør denne test i Cypress Test Runner for at se den i aktion. Du skulle se browseren navigere til Cypress Kitchen Sink-webstedet, klikke på linket "type" og verificere URL'en.
Cypress-kommandoer
Cypress tilbyder en lang række kommandoer til interaktion med din applikation. Her er nogle af de mest almindeligt anvendte kommandoer:
- `cy.visit(url)`: Navigerer til den angivne URL.
- `cy.get(selector)`: Vælger et element ved hjælp af en CSS-vælger.
- `cy.contains(content)`: Vælger et element, der indeholder den angivne tekst.
- `cy.click()`: Klikker på det valgte element.
- `cy.type(text)`: Indtaster tekst i det valgte element.
- `cy.clear()`: Rydder indholdet af et input- eller textarea-element.
- `cy.submit()`: Indsender en formular.
- `cy.check()`: Marker et afkrydsningsfelt eller en radio-knap.
- `cy.uncheck()`: Fjerner markeringen af et afkrydsningsfelt.
- `cy.select(value)`: Vælger en mulighed fra en rullemenu.
- `cy.scrollTo(position)`: Ruller siden til den angivne position.
- `cy.trigger(event)`: Udløser en DOM-hændelse på det valgte element.
- `cy.request(url, options)`: Foretager en HTTP-anmodning til den angivne URL.
- `cy.intercept(route, handler)`: Opfanger HTTP-anmodninger, der matcher den angivne rute.
- `cy.wait(time)`: Venter i den angivne tidsperiode.
- `cy.reload()`: Genindlæser den aktuelle side.
- `cy.go(direction)`: Navigerer til den forrige eller næste side i browserens historik.
- `cy.url()`: Henter den aktuelle URL på siden.
- `cy.title()`: Henter titlen på siden.
- `cy.window()`: Henter vinduesobjektet.
- `cy.document()`: Henter dokumentobjektet.
- `cy.viewport(width, height)`: Indstiller viewport-størrelsen.
Dette er blot nogle få af de mange kommandoer, der er tilgængelige i Cypress. Se Cypress-dokumentationen for en komplet liste over kommandoer og deres muligheder.
Påstande i Cypress
Påstande bruges til at verificere den forventede adfærd af din applikation. Cypress tilbyder et rigt sæt af indbyggede påstande, som du kan bruge til at kontrollere tilstanden af elementer, URL'en, titlen og mere. Påstande er kædet efter Cypress-kommandoer ved hjælp af metoden `.should()`.
Her er nogle eksempler på almindelige påstande:
- `.should('be.visible')`: Påstår, at et element er synligt.
- `.should('not.be.visible')`: Påstår, at et element ikke er synligt.
- `.should('be.enabled')`: Påstår, at et element er aktiveret.
- `.should('be.disabled')`: Påstår, at et element er deaktiveret.
- `.should('have.text', 'expected text')`: Påstår, at et element har den angivne tekst.
- `.should('contain', 'expected text')`: Påstår, at et element indeholder den angivne tekst.
- `.should('have.value', 'expected value')`: Påstår, at et element har den angivne værdi.
- `.should('have.class', 'expected class')`: Påstår, at et element har den angivne klasse.
- `.should('have.attr', 'attribute name', 'expected value')`: Påstår, at et element har det angivne attribut og værdi.
- `.should('have.css', 'css property', 'expected value')`: Påstår, at et element har den angivne CSS-egenskab og værdi.
- `.should('have.length', expected length)`: Påstår, at et element har den angivne længde (f.eks. antallet af elementer i en liste).
Du kan også oprette brugerdefinerede påstande, der passer til dine specifikke behov.
Bedste praksis for at skrive Cypress-tests
Ved at følge bedste praksis kan du hjælpe dig med at skrive mere vedligeholdelsesvenlige, pålidelige og effektive Cypress-tests. Her er nogle anbefalinger:
- Skriv klare og præcise tests: Hver test skal fokusere på en specifik funktionalitet eller et scenarie. Undgå at skrive alt for komplekse tests, der er vanskelige at forstå og vedligeholde.
- Brug meningsfulde testnavne: Giv dine tests beskrivende navne, der klart angiver, hvad de tester.
- Undgå hardkodning af værdier: Brug variabler eller konfigurationsfiler til at gemme værdier, der kan ændre sig over tid.
- Brug brugerdefinerede kommandoer: Opret brugerdefinerede kommandoer for at indkapsle genanvendelig logik og gøre dine tests mere læsbare.
- Isoler tests: Hver test skal være uafhængig af andre tests. Undgå at stole på applikationens tilstand fra tidligere tests.
- Ryd op efter tests: Nulstil applikationens tilstand efter hver test for at sikre, at efterfølgende tests starter fra bunden.
- Brug dataattributter: Brug dataattributter (f.eks. `data-testid`) til at vælge elementer i dine tests. Dataattributter er mindre tilbøjelige til at ændre sig end CSS-klasser eller -ID'er, hvilket gør dine tests mere modstandsdygtige over for ændringer i brugergrænsefladen.
- Undgå eksplicitte waits: Cypress venter automatisk på, at elementer bliver synlige eller interaktive. Undgå at bruge eksplicitte waits (f.eks. `cy.wait()`), medmindre det er absolut nødvendigt.
- Test brugerflows: Fokuser på at teste brugerflows i stedet for individuelle komponenter. Dette vil hjælpe dig med at sikre, at din applikation fungerer korrekt fra brugerens perspektiv.
- Kør tests regelmæssigt: Integrer Cypress-tests i din CI/CD-pipeline, og kør dem regelmæssigt for at fange fejl tidligt i udviklingsprocessen.
Avancerede Cypress-teknikker
Stubbing og Mocking
Cypress giver dig mulighed for at stumpe netværksanmodninger og -svar, hvilket gør det muligt for dig at simulere forskellige scenarier og teste din applikations fejlhåndtering. Dette er især nyttigt til test af funktioner, der er afhængige af eksterne API'er eller tjenester.
For at stumpe en netværksanmodning kan du bruge kommandoen `cy.intercept()`. For eksempel stumper koden nedenfor en GET-anmodning til `/api/users` og returnerer et mock-svar:
cy.intercept('GET', '/api/users', {
statusCode: 200,
body: [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' }
]
}).as('getUsers')
Du kan derefter vente på den opfangede anmodning ved hjælp af `cy.wait('@getUsers')` og verificere, at din applikation håndterer mock-svaret korrekt.
Arbejde med lokal lagring og cookies
Cypress tilbyder kommandoer til interaktion med lokal lagring og cookies. Du kan bruge disse kommandoer til at indstille, hente og rydde lokal lagring og cookies i dine tests.
For at indstille et element i lokal lagring kan du bruge kommandoen `cy.window()` til at få adgang til vinduesobjektet og derefter bruge metoden `localStorage.setItem()`. For eksempel:
cy.window().then((win) => {
win.localStorage.setItem('myKey', 'myValue')
})
For at hente et element i lokal lagring kan du bruge kommandoen `cy.window()` og derefter bruge metoden `localStorage.getItem()`. For eksempel:
cy.window().then((win) => {
const value = win.localStorage.getItem('myKey')
expect(value).to.equal('myValue')
})
For at indstille en cookie kan du bruge kommandoen `cy.setCookie()`. For eksempel:
cy.setCookie('myCookie', 'myCookieValue')
For at hente en cookie kan du bruge kommandoen `cy.getCookie()`. For eksempel:
cy.getCookie('myCookie').should('have.property', 'value', 'myCookieValue')
Håndtering af filoverførsler
Cypress tilbyder et plugin kaldet `cypress-file-upload`, der forenkler filoverførsler i dine tests. For at installere plugin'et skal du køre følgende kommando:
npm install -D cypress-file-upload
Tilføj derefter følgende linje til din fil `cypress/support/commands.js`:
import 'cypress-file-upload';
Du kan derefter bruge kommandoen `cy.uploadFile()` til at uploade en fil. For eksempel:
cy.get('input[type="file"]').attachFile('example.txt')
Arbejde med IFrames
Testning af IFrames kan være vanskelig, men Cypress giver en måde at interagere med dem på. Du kan bruge kommandoen `cy.frameLoaded()` til at vente på, at en IFrame indlæses, og derefter bruge kommandoen `cy.iframe()` til at få IFrame's dokumentobjekt.
cy.frameLoaded('#myIframe')
cy.iframe('#myIframe').find('button').click()
Cypress og Continuous Integration/Continuous Deployment (CI/CD)
At integrere Cypress i din CI/CD-pipeline er afgørende for at sikre kvaliteten af din applikation. Du kan køre Cypress-tests i headless mode i dit CI/CD-miljø. Sådan gør du:
- Installer Cypress: Sørg for, at Cypress er installeret som en afhængighed i dit projekt.
- Konfigurer CI/CD: Konfigurer din CI/CD-pipeline til at køre Cypress-tests efter hver build.
- Kør Cypress Headlessly: Brug kommandoen `cypress run` til at køre Cypress-tests i headless mode.
Eksempel på CI/CD-konfiguration (ved hjælp af GitHub Actions):
name: Cypress Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
cypress-run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- name: Install dependencies
run: npm install
- name: Cypress run
uses: cypress-io/github-action@v5
with:
start: npm start
wait-on: 'http://localhost:3000'
Denne konfiguration vil køre Cypress-tests, når koden skubbes til grenen `main`, eller en pull-anmodning oprettes mod grenen `main`. Handlingen `cypress-io/github-action` forenkler processen med at køre Cypress-tests i GitHub Actions.
Debugging af Cypress-tests
Cypress tilbyder fremragende debugging-værktøjer, der hjælper dig med at identificere og løse problemer i dine tests. Her er nogle tips til debugging af Cypress-tests:
- Brug Cypress Test Runner: Cypress Test Runner giver en visuel grænseflade til at køre og debugge dine tests. Du kan gå gennem dine tests en kommando ad gangen, inspicere applikationens tilstand og se detaljerede fejlmeddelelser.
- Brug kommandoen `cy.pause()`: Kommandoen `cy.pause()` pauser udførelsen af din test og giver dig mulighed for at inspicere applikationens tilstand i browserens udviklerværktøjer.
- Brug kommandoen `cy.debug()`: Kommandoen `cy.debug()` udskriver det valgte element til konsollen, så du kan inspicere dets egenskaber og attributter.
- Brug browserens udviklerværktøjer: Browserens udviklerværktøjer giver en masse information om din applikation, herunder DOM'en, netværksanmodninger og konsollogfiler.
- Læs fejlmeddelelser omhyggeligt: Cypress giver detaljerede fejlmeddelelser, der kan hjælpe dig med at identificere årsagen til fejlen. Vær opmærksom på fejlmeddelelsen og stack tracen.
Cypress vs. Andre testrammer
Mens Cypress er en kraftfuld end-to-end-testramme, er det vigtigt at forstå, hvordan den sammenlignes med andre populære muligheder. Her er et kort overblik:
- Selenium: Selenium er en udbredt automatiserings testramme. Selvom den er fleksibel og understøtter flere sprog, kan den være kompleks at opsætte og vedligeholde. Cypress tilbyder en enklere og mere udviklervenlig oplevelse, især for JavaScript-baserede applikationer.
- Puppeteer: Puppeteer er et Node-bibliotek, der leverer en API på højt niveau til styring af headless Chrome eller Chromium. Det er fremragende til scraping og automatisering af browseropgaver, men kan kræve mere manuel konfiguration sammenlignet med Cypress til end-to-end-testning.
- Playwright: Playwright er en anden automatiseringsramme på tværs af browsere udviklet af Microsoft. Den deler ligheder med Puppeteer, men tilbyder bredere browserunderstøttelse. Cypress har en unik tidsrejsende debugger og en mere integreret testoplevelse.
Valget af ramme afhænger af dit projekts specifikke behov og krav. Cypress er et fremragende valg til moderne webapplikationer, der kræver hurtig, pålidelig og udviklervenlig end-to-end-testning.
Eksempler fra den virkelige verden på Cypress i aktion
Lad os udforske et par eksempler fra den virkelige verden på, hvordan Cypress kan bruges til at teste forskellige typer webapplikationer:
Test af en e-handelsapplikation
Du kan bruge Cypress til at teste forskellige brugerforløb i en e-handelsapplikation, såsom:
- Søgning efter produkter
- Tilføjelse af produkter til kurven
- Bestilling og afgivelse af en ordre
- Håndtering af kontoindstillinger
Her er et eksempel på en Cypress-test, der verificerer, at en bruger med succes kan tilføje et produkt til sin kurv:
it('Tilføjer et produkt til kurven', () => {
cy.visit('/products')
cy.get('.product-card').first().find('button').click()
cy.get('.cart-count').should('have.text', '1')
})
Test af en social medieapplikation
Du kan bruge Cypress til at teste brugerinteraktioner i en social medieapplikation, såsom:
- Oprettelse af et nyt opslag
- Liker et opslag
- Kommentering på et opslag
- Følg andre brugere
Her er et eksempel på en Cypress-test, der verificerer, at en bruger med succes kan oprette et nyt opslag:
it('Opretter et nyt opslag', () => {
cy.visit('/profile')
cy.get('#new-post-textarea').type('Hej, verden!')
cy.get('#submit-post-button').click()
cy.get('.post').first().should('contain', 'Hej, verden!')
})
Test af en bankapplikation
For bankapplikationer kan Cypress bruges til at teste kritiske funktioner såsom:
- Sikker login
- Kontrol af kontosaldoer
- Overførsel af midler
- Håndtering af modtagere
En test til at verificere en pengeoverførsel kan se sådan ud (med passende stubbing for sikkerhed):
it('Overfører midler med succes', () => {
cy.visit('/transfer')
cy.get('#recipient-account').type('1234567890')
cy.get('#amount').type('100')
cy.intercept('POST', '/api/transfer', { statusCode: 200, body: { success: true } }).as('transfer')
cy.get('#transfer-button').click()
cy.wait('@transfer')
cy.get('.success-message').should('be.visible')
})
Konklusion
Cypress er en kraftfuld og alsidig end-to-end-testramme, der kan hjælpe dig med at sikre kvaliteten og pålideligheden af dine webapplikationer. Dens udviklervenlige API, kraftfulde funktioner og fremragende ydeevne gør det til et populært valg blandt udviklere og QA-ingeniører verden over. Ved at følge den bedste praksis, der er beskrevet i denne guide, kan du skrive effektive Cypress-tests, der hjælper dig med at fange fejl tidligt i udviklingsprocessen og levere software af høj kvalitet til dine brugere.
Efterhånden som webapplikationer fortsætter med at udvikle sig, vil betydningen af end-to-end-testning kun øges. At omfavne Cypress og integrere det i dit udviklingsworkflow vil give dig mulighed for at opbygge mere robuste, pålidelige og brugervenlige weboplevelser.