Supertest — это библиотека для интеграционного тестирования HTTP-запросов, которая часто используется в связке с Mocha для тестирования API и серверных приложений. Она предоставляет простой и удобный способ отправки запросов к серверу, проверки ответов и ассертов, которые необходимы для тестирования реальных HTTP-ресурсов.
Supertest активно используется при тестировании RESTful API, так как она значительно упрощает процесс работы с HTTP-запросами, позволяет легко интегрировать тесты в текущие пайплайны и дает гибкость для проверки различных сценариев.
Для начала необходимо установить Supertest и Mocha в проект. Для этого в командной строке используется следующая команда:
npm install --save-dev supertest mocha
После этого библиотека будет доступна для импорта в файлах тестов.
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-функция, которая обрабатывает результат.
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 или в теле запроса. Это полезно при тестировании фильтров, сортировок и других динамических параметров, которые могут изменять ответ сервера.
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(), что позволяет отправлять параметры в строке
запроса.
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 предоставляет множество встроенных методов для проверки различных аспектов ответа, таких как статус код, тип контента, заголовки и содержимое.
Основные ассерты:
Пример с ассертом для проверки содержимого:
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 пайплайнах, где важно проверять работоспособность API после каждого изменения кода. С помощью Mocha можно организовать тесты в виде последовательных шагов, где каждый запрос проверяет корректность работы серверных эндпоинтов.
Пример интеграции в CI/CD:
Таким образом, использование Supertest помогает не только тестировать локально, но и обеспечить бесперебойную работу API в продакшене.