En omfattande guide till Cypress, det kraftfulla end-to-end-testramverket, som täcker installation, skrivande av tester, felsökning, CI/CD-integration och bästa praxis.
Cypress: Den Ultimata Guiden för End-to-End-testning av Webbapplikationer
I dagens snabbt utvecklande webbutvecklingslandskap är det avgörande att säkerställa kvaliteten och tillförlitligheten hos webbapplikationer. End-to-End (E2E)-testning spelar en avgörande roll för att verifiera att alla komponenter i en applikation fungerar sömlöst tillsammans ur användarens perspektiv. Cypress har framstått som ett ledande E2E-testramverk och erbjuder en utvecklarvänlig upplevelse, kraftfulla funktioner och utmärkt prestanda. Denna omfattande guide kommer att guida dig genom allt du behöver veta för att komma igång med Cypress och effektivt testa dina webbapplikationer.
Vad är Cypress?
Cypress är ett nästa generations testverktyg för front-end, byggt för den moderna webben. Till skillnad från traditionella testramverk som kör tester i en webbläsare, fungerar Cypress direkt i webbläsaren, vilket ger dig oöverträffad kontroll och insyn i din applikations beteende. Den är utformad för att vara snabb, pålitlig och enkel att använda, vilket gör den till ett populärt val bland utvecklare och QA-ingenjörer världen över. Cypress är skrivet i JavaScript och körs i webbläsaren, vilket gör den mycket prestandamässig och erbjuder oöverträffad tillgång till applikationens interna delar.
Viktiga fördelar med att använda Cypress
- Utvecklarvänlig: Cypress tillhandahåller ett rent och intuitivt API, vilket gör det enkelt att skriva och felsöka tester.
- Tidsresor: Cypress tar ögonblicksbilder av din applikations tillstånd under varje testkommando, vilket gör att du kan gå tillbaka i tiden och se exakt vad som hände vid någon tidpunkt.
- Realtidsinläsningar: Cypress laddar automatiskt om när du gör ändringar i dina tester, vilket ger omedelbar feedback.
- Automatisk väntan: Cypress väntar automatiskt på att element ska bli synliga eller interaktiva innan åtgärder utförs, vilket eliminerar behovet av explicita väntningar.
- Nätverkskontroll: Cypress låter dig stubba nätverksförfrågningar och svar, vilket gör att du kan simulera olika scenarier och testa din applikations felhantering.
- Felsökningsbarhet: Cypress tillhandahåller utmärkta felsökningsverktyg, inklusive en kraftfull felsökare och detaljerade felmeddelanden.
- Testning över flera webbläsare: Cypress stöder flera webbläsare, inklusive Chrome, Firefox, Edge och Electron.
- Huvudlös testning: Kör tester i huvudlöst läge för snabbare exekvering i CI/CD-miljöer.
- Inbyggda försäkringar: Cypress tillhandahåller en rik uppsättning inbyggda försäkringar för att verifiera det förväntade beteendet hos din applikation.
Installation och inställning
Att komma igång med Cypress är enkelt. Så här installerar du det:
- Förutsättningar: Se till att du har Node.js och npm (Node Package Manager) installerat på ditt system. Du kan ladda ner dem från den officiella Node.js-webbplatsen.
- Installera Cypress: Öppna din terminal eller kommandotolk, navigera till din projektkatalog och kör följande kommando:
- Öppna Cypress: När installationen är klar kan du öppna Cypress Test Runner genom att köra:
npm install cypress --save-dev
npx cypress open
Detta kommando kommer att starta Cypress Test Runner, som tillhandahåller ett grafiskt gränssnitt för att köra och felsöka dina tester.
Skriva ditt första Cypress-test
Låt oss skapa ett enkelt test för att verifiera att en webbplats startsida laddas korrekt. Skapa en ny fil med namnet `example.cy.js` i katalogen `cypress/e2e` i ditt projekt.
// cypress/e2e/example.cy.js
describe('Mitt första test', () => {
it('Besöker 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')
})
})
Låt oss bryta ner detta test:
- `describe()`: Definerar en testsvit, som är en samling relaterade tester.
- `it()`: Definerar ett enskilt testfall inom testsviten.
- `cy.visit()`: Navigerar till den angivna URL:en.
- `cy.contains()`: Hittar ett element som innehåller den angivna texten.
- `.click()`: Klickar på det valda elementet.
- `cy.url()`: Hämtar den aktuella URL:en för sidan.
- `.should()`: Gör ett påstående om applikationens tillstånd.
- `cy.get()`: Väljer ett element med hjälp av en CSS-väljare.
- `.type()`: Skriver text i det valda elementet.
- `.should('have.value', 'fake@email.com')`: Påstår att elementets värde är lika med 'fake@email.com'.
Kör det här testet i Cypress Test Runner för att se det i aktion. Du bör se webbläsaren navigera till Cypress Kitchen Sink-webbplatsen, klicka på länken "type" och verifiera URL:en.
Cypress-kommandon
Cypress tillhandahåller ett brett utbud av kommandon för att interagera med din applikation. Här är några av de vanligaste kommandona:
- `cy.visit(url)`: Navigerar till den angivna URL:en.
- `cy.get(selector)`: Väljer ett element med hjälp av en CSS-väljare.
- `cy.contains(content)`: Väljer ett element som innehåller den angivna texten.
- `cy.click()`: Klickar på det valda elementet.
- `cy.type(text)`: Skriver text i det valda elementet.
- `cy.clear()`: Rensa innehållet i ett inmatnings- eller textområdelement.
- `cy.submit()`: Skickar ett formulär.
- `cy.check()`: Markera en kryssruta eller alternativknapp.
- `cy.uncheck()`: Avmarkera en kryssruta.
- `cy.select(value)`: Väljer ett alternativ från en rullgardinsmeny.
- `cy.scrollTo(position)`: Rullar sidan till den angivna positionen.
- `cy.trigger(event)`: Utlöser en DOM-händelse på det valda elementet.
- `cy.request(url, options)`: Gör en HTTP-begäran till den angivna URL:en.
- `cy.intercept(route, handler)`: Avlyssnar HTTP-förfrågningar som matchar den angivna rutten.
- `cy.wait(time)`: Väntar den angivna tiden.
- `cy.reload()`: Laddar om den aktuella sidan.
- `cy.go(direction)`: Navigerar till föregående eller nästa sida i webbläsarens historik.
- `cy.url()`: Hämtar den aktuella URL:en för sidan.
- `cy.title()`: Hämtar titeln på sidan.
- `cy.window()`: Hämtar fönsterobjektet.
- `cy.document()`: Hämtar dokumentobjektet.
- `cy.viewport(width, height)`: Ställer in viewport-storleken.
Det här är bara några av de många kommandon som finns i Cypress. Se Cypress-dokumentationen för en fullständig lista över kommandon och deras alternativ.
Försäkringar i Cypress
Försäkringar används för att verifiera det förväntade beteendet hos din applikation. Cypress tillhandahåller en rik uppsättning inbyggda försäkringar som du kan använda för att kontrollera tillståndet för element, URL:en, titeln och mer. Försäkringar kedjas efter Cypress-kommandon med metoden `.should()`.
Här är några vanliga försäkringsexempel:
- `.should('be.visible')`: Påstår att ett element är synligt.
- `.should('not.be.visible')`: Påstår att ett element inte är synligt.
- `.should('be.enabled')`: Påstår att ett element är aktiverat.
- `.should('be.disabled')`: Påstår att ett element är inaktiverat.
- `.should('have.text', 'expected text')`: Påstår att ett element har den angivna texten.
- `.should('contain', 'expected text')`: Påstår att ett element innehåller den angivna texten.
- `.should('have.value', 'expected value')`: Påstår att ett element har det angivna värdet.
- `.should('have.class', 'expected class')`: Påstår att ett element har den angivna klassen.
- `.should('have.attr', 'attribute name', 'expected value')`: Påstår att ett element har det angivna attributet och värdet.
- `.should('have.css', 'css property', 'expected value')`: Påstår att ett element har den angivna CSS-egenskapen och värdet.
- `.should('have.length', expected length)`: Påstår att ett element har den angivna längden (t.ex. antalet element i en lista).
Du kan också skapa anpassade försäkringar för att passa dina specifika behov.
Bästa praxis för att skriva Cypress-tester
Att följa bästa praxis kan hjälpa dig att skriva mer underhållbara, tillförlitliga och effektiva Cypress-tester. Här är några rekommendationer:
- Skriv tydliga och koncisa tester: Varje test bör fokusera på en specifik funktionalitet eller scenario. Undvik att skriva alltför komplexa tester som är svåra att förstå och underhålla.
- Använd meningsfulla testnamn: Ge dina tester beskrivande namn som tydligt anger vad de testar.
- Undvik hårdkodningsvärden: Använd variabler eller konfigurationsfiler för att lagra värden som kan ändras över tiden.
- Använd anpassade kommandon: Skapa anpassade kommandon för att inkapsla återanvändningsbar logik och göra dina tester mer läsbara.
- Isolera tester: Varje test bör vara oberoende av andra tester. Undvik att förlita dig på applikationens tillstånd från tidigare tester.
- Rensa efter tester: Återställ applikationens tillstånd efter varje test för att säkerställa att efterföljande tester börjar från ett rent utgångsläge.
- Använd dataattribut: Använd dataattribut (t.ex. `data-testid`) för att välja element i dina tester. Dataattribut är mindre benägna att ändras än CSS-klasser eller ID:n, vilket gör dina tester mer motståndskraftiga mot ändringar i användargränssnittet.
- Undvik explicita väntningar: Cypress väntar automatiskt på att element ska bli synliga eller interaktiva. Undvik att använda explicita väntningar (t.ex. `cy.wait()`) om det inte är absolut nödvändigt.
- Testa användarflöden: Fokusera på att testa användarflöden snarare än enskilda komponenter. Detta hjälper dig att säkerställa att din applikation fungerar korrekt ur användarens perspektiv.
- Kör tester regelbundet: Integrera Cypress-tester i din CI/CD-pipeline och kör dem regelbundet för att fånga buggar tidigt i utvecklingsprocessen.
Avancerade Cypress-tekniker
Stubbing och Mocking
Cypress låter dig stubba nätverksförfrågningar och svar, vilket gör att du kan simulera olika scenarier och testa din applikations felhantering. Detta är särskilt användbart för att testa funktioner som är beroende av externa API:er eller tjänster.
För att stubba en nätverksbegäran kan du använda kommandot `cy.intercept()`. Till exempel stubbar koden nedan en GET-begäran till `/api/users` och returnerar ett hånfullt svar:
cy.intercept('GET', '/api/users', {
statusCode: 200,
body: [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' }
]
}).as('getUsers')
Du kan sedan vänta på den avlyssnade begäran med `cy.wait('@getUsers')` och verifiera att din applikation hanterar det hånfulla svaret korrekt.
Arbeta med lokal lagring och cookies
Cypress tillhandahåller kommandon för att interagera med lokal lagring och cookies. Du kan använda dessa kommandon för att ställa in, hämta och rensa lokal lagring och cookies i dina tester.
För att ställa in ett lokalt lagringsobjekt kan du använda kommandot `cy.window()` för att komma åt fönsterobjektet och sedan använda metoden `localStorage.setItem()`. Till exempel:
cy.window().then((win) => {
win.localStorage.setItem('myKey', 'myValue')
})
För att hämta ett lokalt lagringsobjekt kan du använda kommandot `cy.window()` och sedan använda metoden `localStorage.getItem()`. Till exempel:
cy.window().then((win) => {
const value = win.localStorage.getItem('myKey')
expect(value).to.equal('myValue')
})
För att ställa in en cookie kan du använda kommandot `cy.setCookie()`. Till exempel:
cy.setCookie('myCookie', 'myCookieValue')
För att hämta en cookie kan du använda kommandot `cy.getCookie()`. Till exempel:
cy.getCookie('myCookie').should('have.property', 'value', 'myCookieValue')
Hantering av filuppladdningar
Cypress tillhandahåller ett plugin som heter `cypress-file-upload` som förenklar filuppladdningar i dina tester. För att installera pluginet, kör följande kommando:
npm install -D cypress-file-upload
Lägg sedan till följande rad i din fil `cypress/support/commands.js`:
import 'cypress-file-upload';
Du kan sedan använda kommandot `cy.uploadFile()` för att ladda upp en fil. Till exempel:
cy.get('input[type="file"]').attachFile('example.txt')
Arbeta med IFrames
Att testa IFrames kan vara knepigt, men Cypress tillhandahåller ett sätt att interagera med dem. Du kan använda kommandot `cy.frameLoaded()` för att vänta på att en IFrame ska laddas, och sedan använda kommandot `cy.iframe()` för att hämta IFrames dokumentobjekt.
cy.frameLoaded('#myIframe')
cy.iframe('#myIframe').find('button').click()
Cypress och Continuous Integration/Continuous Deployment (CI/CD)
Att integrera Cypress i din CI/CD-pipeline är viktigt för att säkerställa kvaliteten på din applikation. Du kan köra Cypress-tester i huvudlöst läge i din CI/CD-miljö. Så här:
- Installera Cypress: Se till att Cypress är installerat som ett beroende i ditt projekt.
- Konfigurera CI/CD: Konfigurera din CI/CD-pipeline för att köra Cypress-tester efter varje build.
- Kör Cypress huvudlöst: Använd kommandot `cypress run` för att köra Cypress-tester i huvudlöst läge.
Exempel på CI/CD-konfiguration (med 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'
Denna konfiguration kommer att köra Cypress-tester när kod pushas till `main`-grenen eller en pull-begäran skapas mot `main`-grenen. Åtgärden `cypress-io/github-action` förenklar processen att köra Cypress-tester i GitHub Actions.
Felsöka Cypress-tester
Cypress tillhandahåller utmärkta felsökningsverktyg som hjälper dig att identifiera och åtgärda problem i dina tester. Här är några tips för att felsöka Cypress-tester:
- Använd Cypress Test Runner: Cypress Test Runner tillhandahåller ett visuellt gränssnitt för att köra och felsöka dina tester. Du kan gå igenom dina tester ett kommando i taget, inspektera applikationens tillstånd och visa detaljerade felmeddelanden.
- Använd kommandot `cy.pause()`: Kommandot `cy.pause()` pausar utförandet av ditt test och låter dig inspektera applikationens tillstånd i webbläsarens utvecklarverktyg.
- Använd kommandot `cy.debug()`: Kommandot `cy.debug()` skriver ut det valda elementet till konsolen, vilket gör att du kan inspektera dess egenskaper och attribut.
- Använd webbläsarens utvecklarverktyg: Webbläsarens utvecklarverktyg ger en mängd information om din applikation, inklusive DOM, nätverksbegäranden och konsolloggar.
- Läs felmeddelanden noggrant: Cypress tillhandahåller detaljerade felmeddelanden som kan hjälpa dig att identifiera orsaken till felet. Var uppmärksam på felmeddelandet och stackspåret.
Cypress vs. andra testramverk
Även om Cypress är ett kraftfullt end-to-end-testramverk är det viktigt att förstå hur det jämförs med andra populära alternativ. Här är en kort översikt:
- Selenium: Selenium är ett allmänt använt automatiseringsramverk. Även om det är flexibelt och stöder flera språk, kan det vara komplext att konfigurera och underhålla. Cypress erbjuder en enklare och mer utvecklarvänlig upplevelse, särskilt för JavaScript-baserade applikationer.
- Puppeteer: Puppeteer är ett Node-bibliotek som tillhandahåller ett API på hög nivå för att kontrollera huvudlöst Chrome eller Chromium. Det är utmärkt för att skrapa och automatisera webbläsaruppgifter, men kan kräva mer manuell konfiguration jämfört med Cypress för end-to-end-testning.
- Playwright: Playwright är ett annat automatiseringsramverk för flera webbläsare som utvecklats av Microsoft. Det delar likheter med Puppeteer men erbjuder bredare webbläsarstöd. Cypress har en unik tidsresande felsökare och en mer integrerad testupplevelse.
Valet av ramverk beror på ditt projekts specifika behov och krav. Cypress är ett utmärkt val för moderna webbapplikationer som kräver snabb, pålitlig och utvecklarvänlig end-to-end-testning.
Exempel från den verkliga världen av Cypress i aktion
Låt oss utforska några exempel från den verkliga världen på hur Cypress kan användas för att testa olika typer av webbapplikationer:
Testa en e-handelsapplikation
Du kan använda Cypress för att testa olika användarflöden i en e-handelsapplikation, till exempel:
- Söka efter produkter
- Lägga till produkter i kundvagnen
- Kassa och beställning
- Hantera kontoinställningar
Här är ett exempel på ett Cypress-test som verifierar att en användare framgångsrikt kan lägga till en produkt i sin kundvagn:
it('Lägger till en produkt i kundvagnen', () => {
cy.visit('/products')
cy.get('.product-card').first().find('button').click()
cy.get('.cart-count').should('have.text', '1')
})
Testa en social media-applikation
Du kan använda Cypress för att testa användarinteraktioner i en social media-applikation, till exempel:
- Skapa ett nytt inlägg
- Gilla ett inlägg
- Kommentera ett inlägg
- Följa andra användare
Här är ett exempel på ett Cypress-test som verifierar att en användare framgångsrikt kan skapa ett nytt inlägg:
it('Skapar ett nytt inlägg', () => {
cy.visit('/profile')
cy.get('#new-post-textarea').type('Hej världen!')
cy.get('#submit-post-button').click()
cy.get('.post').first().should('contain', 'Hej världen!')
})
Testa en bankapplikation
För bankapplikationer kan Cypress användas för att testa kritiska funktioner som:
- Logga in säkert
- Kontrollera kontosaldon
- Överföra pengar
- Hantera förmånstagare
Ett test för att verifiera en fondöverföring kan se ut så här (med lämplig stubbning för säkerhet):
it('Överför pengar framgångsrikt', () => {
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')
})
Slutsats
Cypress är ett kraftfullt och mångsidigt end-to-end-testramverk som kan hjälpa dig att säkerställa kvaliteten och tillförlitligheten hos dina webbapplikationer. Dess utvecklarvänliga API, kraftfulla funktioner och utmärkta prestanda gör det till ett populärt val bland utvecklare och QA-ingenjörer världen över. Genom att följa bästa praxis som beskrivs i den här guiden kan du skriva effektiva Cypress-tester som hjälper dig att fånga buggar tidigt i utvecklingsprocessen och leverera högkvalitativ programvara till dina användare.
I takt med att webbapplikationer fortsätter att utvecklas kommer vikten av end-to-end-testning bara att öka. Att omfamna Cypress och integrera det i ditt utvecklingsarbetsflöde kommer att ge dig möjlighet att bygga mer robusta, tillförlitliga och användarvänliga webbupplevelser.