Использование supertest

Supertest — это библиотека для интеграционного тестирования HTTP-запросов, которая часто используется в связке с Mocha для тестирования API и серверных приложений. Она предоставляет простой и удобный способ отправки запросов к серверу, проверки ответов и ассертов, которые необходимы для тестирования реальных HTTP-ресурсов.

Supertest активно используется при тестировании RESTful API, так как она значительно упрощает процесс работы с HTTP-запросами, позволяет легко интегрировать тесты в текущие пайплайны и дает гибкость для проверки различных сценариев.

Установка Supertest

Для начала необходимо установить Supertest и Mocha в проект. Для этого в командной строке используется следующая команда:

npm install --save-dev supertest mocha

После этого библиотека будет доступна для импорта в файлах тестов.

Основные функции Supertest

Supertest предоставляет функциональность для выполнения HTTP-запросов, проверки статусов ответов, работы с заголовками, телом ответа и выполнения ассертов.

Запросы

Supertest поддерживает все основные типы HTTP-запросов, включая GET, POST, PUT, DELETE и другие. Каждый запрос может быть настроен с дополнительными параметрами, такими как заголовки, параметры тела запроса и т. д.

Пример использования Supertest для тестирования GET-запроса:

const request = require('supertest');
const app = require('../app'); // Импортируем приложение

describe('GET /api/v1/resource', () => {
  it('should return a 200 status and valid response', (done) => {
    request(app)
      .get('/api/v1/resource')
      .expect(200)
      .expect('Content-Type', /json/)
      .end((err, res) => {
        if (err) return done(err);
        // Проверка содержимого ответа
        done();
      });
  });
});

В этом примере происходит запрос на эндпоинт /api/v1/resource. В ассертах проверяется статус ответа и тип контента. Важно заметить, что в end() передается callback-функция, которая обрабатывает результат.

POST-запросы

Supertest также поддерживает отправку данных с помощью POST, что полезно при тестировании форм, API для создания ресурсов и других операций с телом запроса.

Пример POST-запроса:

describe('POST /api/v1/resource', () => {
  it('should create a new resource and return status 201', (done) => {
    const newResource = {
      name: 'New Resource',
      description: 'Description of new resource'
    };

    request(app)
      .post('/api/v1/resource')
      .send(newResource)
      .expect(201)
      .expect('Content-Type', /json/)
      .end((err, res) => {
        if (err) return done(err);
        // Проверка данных в ответе
        done();
      });
  });
});

В примере отправляется JSON-объект в теле запроса, и происходит проверка, что сервер вернул статус 201 Created.

Работа с параметрами запроса

Supertest позволяет передавать параметры в URL или в теле запроса. Это полезно при тестировании фильтров, сортировок и других динамических параметров, которые могут изменять ответ сервера.

Пример GET с параметрами:

describe('GET /api/v1/resource', () => {
  it('should return resources filtered by query parameters', (done) => {
    request(app)
      .get('/api/v1/resource')
      .query({ name: 'example' })
      .expect(200)
      .end((err, res) => {
        if (err) return done(err);
        // Проверка ответа
        done();
      });
  });
});

В этом примере к URL добавляются параметры с помощью метода query(), что позволяет отправлять параметры в строке запроса.

Пример POST с параметрами:

describe('POST /api/v1/resource', () => {
  it('should return an error when missing required parameters', (done) => {
    const incompleteResource = {
      name: 'Incomplete Resource'
    };

    request(app)
      .post('/api/v1/resource')
      .send(incompleteResource)
      .expect(400)  // Ожидаемый статус ошибки
      .end((err, res) => {
        if (err) return done(err);
        // Проверка ошибки
        done();
      });
  });
});

В данном случае отправляется неполный объект, что вызывает ошибку на сервере, и Supertest проверяет, что статус ответа равен 400 Bad Request.

Ассерты

Ассерты позволяют проверять, что ответ от сервера соответствует ожидаемому. Supertest предоставляет множество встроенных методов для проверки различных аспектов ответа, таких как статус код, тип контента, заголовки и содержимое.

Основные ассерты:

  • expect(status) — проверяет код состояния ответа.
  • expect(header, value) — проверяет заголовки ответа.
  • expect(type) — проверяет тип контента.
  • expect(body) — проверяет содержимое тела ответа.

Пример с ассертом для проверки содержимого:

describe('GET /api/v1/resource', () => {
  it('should return correct resource data', (done) => {
    request(app)
      .get('/api/v1/resource/1')
      .expect(200)
      .expect('Content-Type', /json/)
      .expect((res) => {
        if (!res.body.name || res.body.name !== 'Expected Name') {
          throw new Error('Name field is missing or incorrect');
        }
      })
      .end(done);
  });
});

В этом примере добавлен кастомный ассер, который проверяет, что поле name в теле ответа соответствует ожидаемому значению.

Взаимодействие с сервером

Для правильной работы с Supertest необходимо, чтобы сервер был в состоянии принимать запросы. Чаще всего это достигается с помощью запуска приложения в тестовом режиме.

Пример инициализации сервера в тестах:

const express = require('express');
const app = express();
const request = require('supertest');

app.get('/api/v1/resource', (req, res) => {
  res.status(200).json({ name: 'Resource' });
});

app.listen(3000);

Этот сервер предоставляет простой API для обработки запросов на /api/v1/resource.

Обработка асинхронности

Поскольку тесты в Mocha могут работать с асинхронными операциями, важно правильно обрабатывать их. Supertest работает с асинхронными запросами, и использование done() помогает правильно завершить тесты.

Пример использования асинхронного теста с Supertest:

describe('GET /api/v1/resource', function() {
  it('should return the correct resource asynchronously', async function() {
    const res = await request(app).get('/api/v1/resource');
    assert.equal(res.status, 200);
    assert.equal(res.body.name, 'Resource');
  });
});

Этот пример показывает использование async/await для работы с асинхронными тестами в Mocha. Такой подход позволяет сделать код тестов более читаемым и избегать использования done().

Использование Supertest в CI/CD

Supertest идеально подходит для интеграционного тестирования в CI/CD пайплайнах, где важно проверять работоспособность API после каждого изменения кода. С помощью Mocha можно организовать тесты в виде последовательных шагов, где каждый запрос проверяет корректность работы серверных эндпоинтов.

Пример интеграции в CI/CD:

  1. Создать тестовый сервер с API.
  2. Написать тесты для каждого эндпоинта.
  3. Добавить тесты в пайплайн CI/CD, чтобы проверять все API на корректность перед деплоем.

Таким образом, использование Supertest помогает не только тестировать локально, но и обеспечить бесперебойную работу API в продакшене.