Mjukvaruutveckling

Vad är mjukvarutestning? Enhets- och E2E-test

Vi förklarar skillnaden mellan enhetstest, integrationstest och end-to-end-test, hur mycket av varje som bör skrivas och vad testautomatisering ger projektet.

Aurora YazılımRedaktionen 6 min läsning
Vad är mjukvarutestning? Enhets- och E2E-test
Vad är mjukvarutestning?

Mjukvarutestning är helheten av kontroller som görs för att verifiera att ett program fungerar som förväntat och inte innehåller fel. Tester kan göras för hand eller automatiskt med kod. De tre vanligaste typerna är enhetstest (unit), integrationstest och end-to-end-test (E2E); i ett friskt projekt balanseras de i en pyramidstruktur.

Vad är mjukvarutestning och varför behövs den?

Mjukvarutestning är sättet att bevisa att koden du skrivit verkligen gör det du vill. Att rabattkoden räknas rätt i en webbutik, att samma rum inte kan bokas två gånger i ett hotellsystem eller att ett formulär avvisar felaktiga data säkerställs med tester.

I projekt utan tester riskerar varje ny funktion att förstöra något som tidigare fungerade. Det kallas regression. Automatiska tester minskar den risken; när en ändring görs visar de på några minuter vad som gått sönder.

Tidpunkten då felet hittas avgör kostnaden. Ett fel som fångas under utvecklingen åtgärdas på några minuter; ett fel som en kund hittar i det skarpa systemet kostar pengar, tid och förtroende.

Testtyper: enhet, integration, E2E

Testtyperna skiljer sig åt i vilket område de täcker och hur snabbt de körs. Att testa små delar är snabbt och billigt; att testa hela systemet är långsamt men realistiskt.

TypOmfattningHastighetUnderhållskostnad
EnhetstestEn enskild funktion / komponentMycket snabbLåg
IntegrationstestDelar som arbetar tillsammansMedelMedel
E2E-testHela användarflödetLångsamHög

Vad är ett enhetstest?

Ett enhetstest (unit test) testar en enskild funktion eller klass isolerat från omvärlden. Databas, nätverk eller filsystem kommer inte in i bilden; vid behov efterliknas de med falska objekt (mock). Det körs på millisekunder och pekar ut var felet finns med precision.

Integrationstest

Integrationstest verifierar att flera delar fungerar korrekt tillsammans: applikationen och databasen, tjänst mot tjänst, systemet och ett externt API. De endpoints vi beskriver i inlägget Vad är ett API testas oftast på den här nivån. I flöden som betalning, frakt och marknadsplatsintegration är de här testerna avgörande.

E2E-test

Ett E2E-test (end-to-end) använder systemet som en riktig användare: öppnar webbläsaren, lägger produkten i varukorgen, går till betalningssteget och kontrollerar att ordern skapas. Det är det mest realistiska testet, men också det långsammaste och mest ömtåliga.

Testpyramiden: hur mycket av vilket test?

Testpyramiden är en vanlig modell som beskriver hur mycket av varje testtyp som bör skrivas. Längst ned finns många snabba enhetstest, i mitten färre integrationstest och överst ett fåtal E2E-test som bara täcker de kritiska flödena.

Att pyramiden vänds upp och ned, alltså att man försöker verifiera allt med E2E-test, är ett vanligt misstag. Då blir testtiden lång, testerna går sönder utan anledning och teamet börjar med tiden misstro dem.

Det finns ingen exakt proportion; projekttypen avgör. I mjukvara som är tung på beräkningar väger enhetstesterna mest, medan integrationstesternas andel ökar i ett projekt som kopplas till många externa system.

Exempel med Jest och Playwright

I JavaScript-världen är Jest och Vitest vanliga val för enhetstest och Playwright och Cypress för E2E-test. Nedan ser du ett enkelt enhetstest skrivet för en rabattfunktion.

Vill du fånga typfel redan innan du skriver tester kan du läsa vårt inlägg Vad är TypeScript; typsystemet lättar testbördan något men ersätter inte testerna.

javascriptEnhetstest med Jest
// indirim.js
export function indirimUygula(tutar, oran) {
  if (oran < 0 || oran > 100) throw new Error('Ogiltig andel');
  return Math.round(tutar * (100 - oran)) / 100;
}

// indirim.test.js
import { indirimUygula } from './indirim.js';

test('20 procents rabatt beräknas korrekt', () => {
  expect(indirimUygula(200, 20)).toBe(160);
});

test('ogiltig andel ger fel', () => {
  expect(() => indirimUygula(200, 120)).toThrow();
});
javascriptE2E-test med Playwright
import { test, expect } from '@playwright/test';

test('produkten läggs i varukorgen', async ({ page }) => {
  await page.goto('https://ornek-magaza.test/urun/zeytinyagi');
  await page.getByRole('button', { name: 'Sepete Ekle' }).click();
  await expect(page.getByTestId('sepet-adet')).toHaveText('1');
});

Testautomatisering och CI

Testautomatisering innebär att testerna inte körs för hand utan automatiskt vid varje kodändring. När koden skickas till förvaret kör en CI-pipeline (kontinuerlig integration) testerna; om ett test misslyckas går ändringen inte live.

Upplägget blir allt mer värdefullt när teamet växer. Alla omfattas av samma kvalitetsribba, och fel fångas innan de når kunden.

  1. Utvecklaren gör ändringen i en gren och skickar den till förvaret.
  2. CI-pipelinen installerar beroenden och kör enhets- och integrationstesterna.
  3. E2E-testerna för de kritiska flödena körs i testmiljön.
  4. Om alla tester går igenom släpps koden live efter kodgranskning.

Andra typer av test

Att fungera rätt räcker inte; mjukvaran måste också vara snabb, säker och användbar. Därför finns det andra testtyper vid sidan av de funktionella testerna.

  • Prestandatest: Mäter hur systemet beter sig under belastning. Sidhastigheten är också en del av arbetet med hastighet och prestanda.
  • Säkerhetstest: Letar efter obehörig åtkomst, injektion och liknande sårbarheter.
  • Användbarhetstest: Tittar på om riktiga användare kan använda gränssnittet utan svårigheter; det är en naturlig del av processen för UI/UX-design.
  • Tillgänglighetstest: Kontrollerar att det fungerar för användare av skärmläsare och tangentbord.
  • Visuellt regressionstest: Jämför skärmbilder och fångar oväntade förskjutningar i designen.
  • Tester av kompilerade moduler: Delar som Wasm-moduler, som vi beskriver i inlägget Vad är WebAssembly, behöver också sin egen testkedja.

Vanliga misstag vid testning

Att skriva tester är en färdighet; dåligt skrivna tester kan bli en börda i stället för en hjälp. De vanligaste misstagen är dessa.

  • Att fastna på täckningsprocenten: En hög siffra betyder inte bra tester; det viktiga är att de kritiska beteendena testas.
  • Att testa applikationens interna struktur: När koden skrivs om går testerna sönder utan anledning. Testa beteendet.
  • Ömtåliga E2E-test: Använd lösningar som väntar på att elementet ska synas i stället för fasta väntetider.
  • Att koppla testerna till skarpa data: Testerna ska förbereda sina egna data och sedan städa upp.
  • Att stänga av ett misslyckat test och glömma det: Det förstör snabbt förtroendet för testerna.

Var ska man börja med testning?

Att lägga till hundratals tester på en gång i ett projekt utan några tester är inte realistiskt. Det effektivare är att börja på det mest riskfyllda stället och gå vidare stegvis. Redan att skriva ett test för varje rättat fel bygger på några månader upp ett rejält skyddsnät.

I början bör målet inte vara perfekt täckning utan pålitliga tester. Ett fåtal tester som ger ett konsekvent resultat varje gång är mer värdefulla än många instabila.

  1. Lista funktionerna som rör pengar, lager och användardata.
  2. Skriv först enhetstester för de funktionerna.
  3. Lägg till integrationstest på punkterna som kopplar till externa system.
  4. Sätt upp E2E-test för de två–tre viktigaste användarflödena.
  5. Koppla testerna till CI-pipelinen och gå inte live med ett rött test.

Vad ger tester verksamheten?

För en företagsägare är testning en investering som inte syns men märks. Därför är det viktigt att de kritiska flödena täcks av tester när skräddarsydda mjukvarulösningar utvecklas. En betalsida som kraschar på kampanjdagen eller en butik som visar fel lagersaldo blir mycket dyrare än kostnaden för testerna.

När order-, faktura- och lagerflöden rör sig mellan flera system ökar risken för fel. Därför sänker en testad och förutsägbar struktur i projekt för e-handelsintegration och e-handelsplattform underhållskostnaden på lång sikt.

Vanliga frågor

01Behöver man skriva tester för ett litet projekt?

Du behöver inte testa varje rad, men kritiska funktioner som rör pengar eller data bör alltid testas. Att börja i liten skala gör att du kan ändra tryggt när projektet växer.

02Är manuell testning helt onödig?

Nej. Utforskande manuella tester hittar problem som automatiseringen inte förutsett. Upprepade kontroller bör automatiseras, medan det mänskliga ögat bör ägnas åt att bedöma nya funktioner och upplevelsen.

03Vad är TDD?

Testdriven utveckling (TDD) är en metod där man först skriver ett test som misslyckas och därefter koden som får testet att gå igenom. Det förenklar designen och förhindrar kod utan tester, men det tar tid för teamet att vänja sig vid disciplinen.

04Ska jag använda Jest eller Vitest?

Båda är mogna verktyg för enhetstest och har liknande syntax. I Vite-baserade projekt är Vitest lättare att integrera; i befintliga stora projekt utmärker sig Jest genom sin utbredning.

Mjukvarutestning är sättet att fånga fel före kunden och låta mjukvaran växa tryggt. En balanserad struktur som utgår från enhetstester och säkrar de kritiska flödena med E2E-test är på lång sikt den billigaste vägen. För testad och hållbar mjukvara kan du titta på Auroras mjukvarulösningar och integrationstjänster.