Dansk

En omfattende guide til integrationstest med fokus på API-test ved hjælp af Supertest, der dækker opsætning, bedste praksis og avancerede teknikker til robust applikationstest.

Integrationstest: Behersk API-test med Supertest

Inden for softwareudvikling er det afgørende at sikre, at individuelle komponenter fungerer korrekt isoleret (enhedstest). Men det er lige så vigtigt at verificere, at disse komponenter fungerer problemfrit sammen. Det er her, integrationstest kommer ind i billedet. Integrationstest fokuserer på at validere interaktionen mellem forskellige moduler eller tjenester i en applikation. Denne artikel dykker ned i integrationstest, med særligt fokus på API-test med Supertest, et kraftfuldt og brugervenligt bibliotek til at teste HTTP-assertions i Node.js.

Hvad er integrationstest?

Integrationstest er en type softwaretest, der kombinerer individuelle softwaremoduler og tester dem som en gruppe. Formålet er at afdække fejl i interaktionen mellem integrerede enheder. I modsætning til enhedstest, der fokuserer på individuelle komponenter, verificerer integrationstest dataflowet og kontrolflowet mellem moduler. Almindelige tilgange til integrationstest inkluderer:

I konteksten af API'er indebærer integrationstest at verificere, at forskellige API'er fungerer korrekt sammen, at dataene, der sendes mellem dem, er konsistente, og at det overordnede system fungerer som forventet. Forestil dig for eksempel en e-handelsapplikation med separate API'er til produktstyring, brugergodkendelse og betalingsbehandling. Integrationstest ville sikre, at disse API'er kommunikerer korrekt, så brugerne kan gennemse produkter, logge sikkert ind og gennemføre køb.

Hvorfor er API-integrationstest vigtigt?

API-integrationstest er kritisk af flere grunde:

Overvej en global platform til booking af rejser. API-integrationstest er altafgørende for at sikre problemfri kommunikation mellem API'er, der håndterer flyreservationer, hotelbookinger og betalingsgateways fra forskellige lande. Manglende korrekt integration af disse API'er kan føre til forkerte bookinger, betalingsfejl og en dårlig brugeroplevelse, hvilket negativt påvirker platformens omdømme og omsætning.

Introduktion til Supertest: Et kraftfuldt værktøj til API-test

Supertest er en højniveau-abstraktion til test af HTTP-requests. Det giver en bekvem og flydende API til at sende requests til din applikation og assertere på svarene. Bygget oven på Node.js er Supertest specifikt designet til at teste Node.js HTTP-servere. Det fungerer usædvanligt godt med populære test-frameworks som Jest og Mocha.

Nøglefunktioner i Supertest:

Opsætning af dit testmiljø

Før vi begynder, lad os opsætte et grundlæggende testmiljø. Vi antager, at du har Node.js og npm (eller yarn) installeret. Vi vil bruge Jest som vores test-framework og Supertest til API-test.

  1. Opret et Node.js-projekt:
mkdir api-testing-example
cd api-testing-example
npm init -y
  1. Installer afhængigheder:
npm install --save-dev jest supertest
npm install express  # Eller dit foretrukne framework til at oprette API'en
  1. Konfigurer Jest: Tilføj følgende til din package.json-fil:
{
  "scripts": {
    "test": "jest"
  }
}
  1. Opret et simpelt API-endepunkt: Opret en fil ved navn app.js (eller lignende) med følgende kode:
const express = require('express');
const app = express();
const port = 3000;

app.get('/hello', (req, res) => {
  res.send('Hello, World!');
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

module.exports = app; // Eksporter til test

Skriv din første Supertest-test

Nu hvor vi har vores miljø opsat, lad os skrive en simpel Supertest-test for at verificere vores API-endepunkt. Opret en fil ved navn app.test.js (eller lignende) i roden af dit projekt:

const request = require('supertest');
const app = require('./app');

describe('GET /hello', () => {
  it('svarer med 200 OK og returnerer "Hello, World!"', async () => {
    const response = await request(app).get('/hello');
    expect(response.statusCode).toBe(200);
    expect(response.text).toBe('Hello, World!');
  });
});

Forklaring:

For at køre testen, udfør følgende kommando i din terminal:

npm test

Hvis alt er sat korrekt op, skulle du se testen bestå.

Avancerede Supertest-teknikker

Supertest tilbyder en bred vifte af funktioner til avanceret API-test. Lad os udforske nogle af dem.

1. Afsendelse af request-bodies

For at sende data i request-body'en kan du bruge .send()-metoden. Lad os for eksempel oprette et endepunkt, der accepterer JSON-data:

app.post('/users', express.json(), (req, res) => {
  const { name, email } = req.body;
  // Simuler oprettelse af en bruger i en database
  const user = { id: Date.now(), name, email };
  res.status(201).json(user);
});

Her er, hvordan du kan teste dette endepunkt ved hjælp af Supertest:

describe('POST /users', () => {
  it('opretter en ny bruger', async () => {
    const userData = {
      name: 'John Doe',
      email: 'john.doe@example.com',
    };

    const response = await request(app)
      .post('/users')
      .send(userData)
      .expect(201);

    expect(response.body).toHaveProperty('id');
    expect(response.body.name).toBe(userData.name);
    expect(response.body.email).toBe(userData.email);
  });
});

Forklaring:

2. Indstilling af headers

For at indstille brugerdefinerede headers i dine requests kan du bruge .set()-metoden. Dette er nyttigt til at indstille godkendelsestokens, content-types eller andre brugerdefinerede headers.

describe('GET /protected', () => {
  it('kræver godkendelse', async () => {
    const response = await request(app).get('/protected').expect(401);
  });

  it('returnerer 200 OK med et gyldigt token', async () => {
    // Simuler at få et gyldigt token
    const token = 'valid-token';

    const response = await request(app)
      .get('/protected')
      .set('Authorization', `Bearer ${token}`)
      .expect(200);

    expect(response.text).toBe('Protected Resource');
  });
});

Forklaring:

3. Håndtering af cookies

Supertest kan også håndtere cookies. Du kan indstille cookies ved hjælp af .set('Cookie', ...)-metoden, eller du kan bruge .cookies-egenskaben til at tilgå og ændre cookies.

4. Test af filuploads

Supertest kan bruges til at teste API-endepunkter, der håndterer filuploads. Du kan bruge .attach()-metoden til at vedhæfte filer til requesten.

5. Brug af assertion-biblioteker (Chai)

Selvom Jests indbyggede assertion-bibliotek er tilstrækkeligt i mange tilfælde, kan du også bruge mere kraftfulde assertion-biblioteker som Chai med Supertest. Chai giver en mere udtryksfuld og fleksibel assertion-syntaks. For at bruge Chai skal du installere det:

npm install --save-dev chai

Derefter kan du importere Chai i din testfil og bruge dens assertions:

const request = require('supertest');
const app = require('./app');
const chai = require('chai');
const expect = chai.expect;

describe('GET /hello', () => {
  it('svarer med 200 OK og returnerer "Hello, World!"', async () => {
    const response = await request(app).get('/hello');
    expect(response.statusCode).to.equal(200);
    expect(response.text).to.equal('Hello, World!');
  });
});

Bemærk: Du skal muligvis konfigurere Jest til at fungere korrekt med Chai. Dette indebærer ofte at tilføje en opsætningsfil, der importerer Chai og konfigurerer det til at fungere med Jests globale expect.

6. Genbrug af agenter

For tests, der kræver opsætning af et specifikt miljø (f.eks. godkendelse), er det ofte en fordel at genbruge en Supertest-agent. Dette undgår overflødig opsætningskode i hver testcase.

describe('Godkendte API-tests', () => {
  let agent;

  beforeAll(() => {
    agent = request.agent(app); // Opret en vedvarende agent
    // Simuler godkendelse
    return agent
      .post('/login')
      .send({ username: 'testuser', password: 'password123' });
  });

  it('kan tilgå en beskyttet ressource', async () => {
    const response = await agent.get('/protected').expect(200);
    expect(response.text).toBe('Protected Resource');
  });

  it('kan udføre andre handlinger, der kræver godkendelse', async () => {
    // Udfør andre godkendte handlinger her
  });
});

I dette eksempel opretter vi en Supertest-agent i beforeAll-hooket og godkender agenten. Efterfølgende tests inden for describe-blokken kan derefter genbruge denne godkendte agent uden at skulle godkende igen for hver test.

Bedste praksis for API-integrationstest med Supertest

For at sikre effektiv API-integrationstest, overvej følgende bedste praksis:

Almindelige fejl, der skal undgås

Konklusion

API-integrationstest er en essentiel del af softwareudviklingsprocessen. Ved at bruge Supertest kan du nemt skrive omfattende og pålidelige API-integrationstests, der hjælper med at sikre kvaliteten og stabiliteten af din applikation. Husk at fokusere på at teste end-to-end arbejdsgange, bruge realistiske data, isolere dine tests og automatisere din testproces. Ved at følge disse bedste praksisser kan du markant reducere risikoen for integrationsproblemer og levere et mere robust og pålideligt produkt.

Efterhånden som API'er fortsat driver moderne applikationer og microservices-arkitekturer, vil vigtigheden af robust API-test, og især integrationstest, kun fortsætte med at vokse. Supertest giver et kraftfuldt og tilgængeligt værktøjssæt for udviklere over hele verden til at sikre pålideligheden og kvaliteten af deres API-interaktioner.