Български

Цялостно ръководство за интеграционно тестване с фокус върху API тестването чрез Supertest, обхващащо настройка, добри практики и напреднали техники.

Интеграционно тестване: Овладяване на API тестването със Supertest

В сферата на софтуерната разработка, гарантирането, че отделните компоненти функционират правилно в изолация (unit тестване), е от решаващо значение. Въпреки това е също толкова важно да се провери дали тези компоненти работят безпроблемно заедно. Тук се намесва интеграционното тестване. Интеграционното тестване се фокусира върху валидирането на взаимодействието между различни модули или услуги в рамките на едно приложение. Тази статия се задълбочава в интеграционното тестване, като се фокусира конкретно върху API тестването със Supertest – мощна и лесна за употреба библиотека за тестване на HTTP твърдения в Node.js.

Какво е интеграционно тестване?

Интеграционното тестване е вид софтуерно тестване, което комбинира отделни софтуерни модули и ги тества като група. Целта му е да разкрие дефекти във взаимодействията между интегрираните единици. За разлика от unit тестването, което се фокусира върху отделни компоненти, интеграционното тестване проверява потока от данни и контролния поток между модулите. Често срещаните подходи за интеграционно тестване включват:

В контекста на API, интеграционното тестване включва проверка дали различните API работят правилно заедно, дали данните, предавани между тях, са последователни и дали цялостната система функционира както се очаква. Представете си например приложение за електронна търговия с отделни API за управление на продукти, удостоверяване на потребители и обработка на плащания. Интеграционното тестване би гарантирало, че тези API комуникират правилно, позволявайки на потребителите да разглеждат продукти, да влизат сигурно в системата и да извършват покупки.

Защо API интеграционното тестване е важно?

API интеграционното тестване е от критично значение по няколко причини:

Да вземем за пример глобална платформа за резервации на пътувания. API интеграционното тестване е от първостепенно значение, за да се осигури гладка комуникация между API, обработващи самолетни резервации, хотелски резервации и портали за плащане от различни държави. Неправилната интеграция на тези API може да доведе до грешни резервации, неуспешни плащания и лошо потребителско изживяване, което ще се отрази негативно на репутацията и приходите на платформата.

Представяне на Supertest: Мощен инструмент за API тестване

Supertest е абстракция от високо ниво за тестване на HTTP заявки. Той предоставя удобен и флуиден API за изпращане на заявки до вашето приложение и проверка на отговорите. Създаден върху Node.js, Supertest е специално проектиран за тестване на Node.js HTTP сървъри. Работи изключително добре с популярни рамки за тестване като Jest и Mocha.

Ключови характеристики на Supertest:

Настройка на вашата тестова среда

Преди да започнем, нека настроим базова тестова среда. Ще приемем, че имате инсталирани Node.js и npm (или yarn). Ще използваме Jest като наша рамка за тестване и Supertest за API тестване.

  1. Създайте Node.js проект:
mkdir api-testing-example
cd api-testing-example
npm init -y
  1. Инсталирайте зависимостите:
npm install --save-dev jest supertest
npm install express  # Или предпочитаната от вас рамка за създаване на API
  1. Конфигурирайте Jest: Добавете следното във вашия package.json файл:
{
  "scripts": {
    "test": "jest"
  }
}
  1. Създайте проста API крайна точка (endpoint): Създайте файл с име app.js (или подобно) със следния код:
const express = require('express');
const app = express();
const port = 3000;

app.get('/hello', (req, res) => {
  res.send('Здравей, свят!');
});

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

module.exports = app; // Експортиране за тестване

Написване на първия ви Supertest тест

Сега, след като сме настроили средата си, нека напишем прост Supertest тест, за да проверим нашата API крайна точка. Създайте файл с име app.test.js (или подобно) в основната директория на вашия проект:

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

describe('GET /hello', () => {
  it('отговаря с 200 OK и връща \"Здравей, свят!\"', async () => {
    const response = await request(app).get('/hello');
    expect(response.statusCode).toBe(200);
    expect(response.text).toBe('Здравей, свят!');
  });
});

Обяснение:

За да изпълните теста, изпълнете следната команда във вашия терминал:

npm test

Ако всичко е настроено правилно, трябва да видите, че тестът преминава успешно.

Напреднали техники със Supertest

Supertest предлага широк набор от функции за напреднало API тестване. Нека разгледаме някои от тях.

1. Изпращане на тяло на заявката (Request Body)

За да изпратите данни в тялото на заявката, можете да използвате метода .send(). Например, нека създадем крайна точка, която приема JSON данни:

app.post('/users', express.json(), (req, res) => {
  const { name, email } = req.body;
  // Симулиране на създаване на потребител в база данни
  const user = { id: Date.now(), name, email };
  res.status(201).json(user);
});

Ето как можете да тествате тази крайна точка, използвайки Supertest:

describe('POST /users', () => {
  it('създава нов потребител', 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);
  });
});

Обяснение:

2. Задаване на хедъри

За да зададете персонализирани хедъри във вашите заявки, можете да използвате метода .set(). Това е полезно за задаване на токени за удостоверяване, типове съдържание или други персонализирани хедъри.

describe('GET /protected', () => {
  it('изисква удостоверяване', async () => {
    const response = await request(app).get('/protected').expect(401);
  });

  it('връща 200 OK с валиден токен', async () => {
    // Симулиране на получаване на валиден токен
    const token = 'valid-token';

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

    expect(response.text).toBe('Защитен ресурс');
  });
});

Обяснение:

3. Работа с бисквитки (Cookies)

Supertest може да работи и с бисквитки. Можете да зададете бисквитки с метода .set('Cookie', ...) или да използвате свойството .cookies за достъп и промяна на бисквитки.

4. Тестване на качване на файлове

Supertest може да се използва за тестване на API крайни точки, които обработват качване на файлове. Можете да използвате метода .attach(), за да прикачите файлове към заявката.

5. Използване на библиотеки за твърдения (Chai)

Въпреки че вградената в Jest библиотека за твърдения е достатъчна за много случаи, можете да използвате и по-мощни библиотеки като Chai със Supertest. Chai предоставя по-изразителен и гъвкав синтаксис за твърдения. За да използвате Chai, ще трябва да го инсталирате:

npm install --save-dev chai

След това можете да импортирате Chai във вашия тестов файл и да използвате неговите твърдения:

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

describe('GET /hello', () => {
  it('отговаря с 200 OK и връща \"Здравей, свят!\"', async () => {
    const response = await request(app).get('/hello');
    expect(response.statusCode).to.equal(200);
    expect(response.text).to.equal('Здравей, свят!');
  });
});

Забележка: Може да се наложи да конфигурирате Jest да работи правилно с Chai. Това често включва добавяне на файл за настройка, който импортира Chai и го конфигурира да работи с глобалния expect на Jest.

6. Преизползване на агенти

За тестове, които изискват настройка на специфична среда (напр. удостоверяване), често е полезно да се преизползва Supertest агент. Това избягва излишен код за настройка във всеки тестов случай.

describe('Тестове на удостоверен API', () => {
  let agent;

  beforeAll(() => {
    agent = request.agent(app); // Създаване на постоянен агент
    // Симулиране на удостоверяване
    return agent
      .post('/login')
      .send({ username: 'testuser', password: 'password123' });
  });

  it('може да достъпи защитен ресурс', async () => {
    const response = await agent.get('/protected').expect(200);
    expect(response.text).toBe('Защитен ресурс');
  });

  it('може да изпълнява други действия, изискващи удостоверяване', async () => {
    // Изпълнете други действия, които изискват удостоверяване тук
  });
});

В този пример създаваме Supertest агент в куката (hook) beforeAll и удостоверяваме агента. Последващите тестове в рамките на блока describe могат да преизползват този удостоверен агент, без да се налага повторно удостоверяване за всеки тест.

Добри практики за API интеграционно тестване със Supertest

За да осигурите ефективно API интеграционно тестване, вземете предвид следните добри практики:

Често срещани грешки, които трябва да се избягват

Заключение

API интеграционното тестване е съществена част от процеса на разработка на софтуер. С помощта на Supertest можете лесно да пишете изчерпателни и надеждни API интеграционни тестове, които помагат да се гарантира качеството и стабилността на вашето приложение. Не забравяйте да се съсредоточите върху тестването на цялостни работни потоци, използването на реалистични данни, изолирането на тестовете и автоматизирането на процеса на тестване. Като следвате тези добри практики, можете значително да намалите риска от проблеми с интеграцията и да предоставите по-стабилен и надежден продукт.

Тъй като API продължават да задвижват съвременните приложения и микросървисните архитектури, значението на стабилното API тестване, и особено на интеграционното тестване, ще продължи да нараства. Supertest предоставя мощен и достъпен набор от инструменти за разработчици по целия свят, за да гарантират надеждността и качеството на своите API взаимодействия.