Гид по технологиям

Тестирование API с Cypress — пошаговое руководство

8 min read Testing Обновлено 30 Dec 2025
Тестирование API с Cypress — руководство
Тестирование API с Cypress — руководство

Слово «API», окружённое абстрактными иконками

Cypress — популярный фреймворк для тестирования приложений на JavaScript. Хотя он изначально ориентирован на тестирование UI и взаимодействия в браузере, Cypress отлично подходит и для тестирования API. Фреймворк умеет отправлять HTTP-запросы и валидировать ответы, что делает его удобным инструментом для автоматизации тестов RESTful API.

Кратко: Cypress позволяет писать полные тесты, охватывающие рабочие сценарии приложения, включая взаимодействие фронтенда и бэкенда.

Зачем использовать Cypress для тестирования API

Пара причин выбора Cypress для API тестирования:

  • Простая интеграция с экосистемой JavaScript/Node.js.
  • Удобный синтаксис и встроенные команды, например cy.request.
  • Возможность комбинировать UI- и API-тесты в одном запуске.

Определение: cy.request — встроенная команда Cypress для выполнения HTTP-запросов к серверу и проверки ответов.

Важно: Cypress использует Node.js для выполнения запросов, поэтому тесты выполняются вне браузерной песочницы и работают напрямую с сервером.

Главная страница Cypress на официальном сайте

План статьи

  • Создаём demo Express API
  • Пишем контроллеры и роуты
  • Настраиваем Cypress
  • Пишем реальные тесты с cy.request
  • Критерии приёмки и тест-кейсы
  • Чек-листы для ролей
  • Альтернативы и когда Cypress может не подойти
  • Методология и рекомендации для CI/CD

Создание простого Express.js REST API

В этом разделе мы создадим демонстрационный сервер на Express и добавим три маршрута: регистрация, список пользователей и логин. Для простоты данные хранятся в массиве в оперативной памяти.

Установите зависимости проекта (локально в каталоге проекта):

npm install cors

Установите Cypress как dev-зависимость:

npm install cypress --save-dev

Добавьте npm-скрипт для запуска Cypress в package.json:

"test": "npx cypress open"

Контроллеры API

Создайте файл controllers/userControllers.js и добавьте код для регистрации, получения списка пользователей и логина.

const users = [];

exports.registerUser = async (req, res) => {
  const { username, password } = req.body;

  try {
    const newUser = { username, password };
    users.push(newUser);
    res.status(201).send({ message: 'User registered successfully' });
  } catch (error) {
    console.error(error);
    res.status(500).send({ message: 'An error occurred!!' });
  }
};

exports.getUsers = async (req, res) => {
  try {
    res.json(users);
  } catch (error) {
    console.error(error);
    res.status(500).send({ message: 'An error occurred!!' });
  }
};

exports.loginUser = async (req, res) => {
  const { username, password } = req.body;

  try {
    const user = users.find((u) =>
          u.username === username && u.password === password);

    if (user) {
      res.status(200).send({ message: 'Login successful' });
    } else {
      res.status(401).send({ message: 'Invalid credentials' });
    }
  } catch (error) {
    console.error(error);
    res.status(500).send({ message: 'An error occurred!!' });
  }
};

Пояснение: для реального приложения замените массив users на базу данных и храните пароли в хешированном виде.

Маршруты

Создайте routes/userRoutes.js с определением маршрутов:

const express = require('express');
const router = express.Router();
const userControllers = require('../controllers/userControllers');

const baseURL = '/v1/api/';

router.post(baseURL + 'register', userControllers.registerUser);
router.get(baseURL + 'users', userControllers.getUsers);
router.post(baseURL + 'login', userControllers.loginUser);

module.exports = router;

Файл server.js

Обновите server.js, чтобы поднять сервер на порту 5000:

const express = require('express');
const cors = require('cors');
const app = express();
const port = 5000;

app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());

const userRoutes = require('./routes/userRoutes');
app.use('/', userRoutes);

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

module.exports = app;

Совет: для разработки используйте nodemon для автоматического перезапуска сервера при изменениях.

Настройка окружения для тестов

Запустите сервер разработки в одном терминале:

node server.js

В другом терминале запустите тесты Cypress:

npm run test

Это откроет десктоп-клиент Cypress. На клиенте выберите E2E Testing, затем Continue, чтобы добавить конфигурационные файлы.

Cypress Testing UI Client running locally on windows pc

После установки в проекте появится папка cypress и файл cypress.config.js. Обновите cypress.config.js, указав базовый URL сервера:

const { defineConfig } = require("cypress");

module.exports = defineConfig({
  chromeWebSecurity: false,
  e2e: {
    baseUrl: 'http://localhost:5000',
    setupNodeEvents(on, config) {
    },
  },
});

Объяснение: baseUrl позволяет в тестах указывать относительные URL вместо полного адреса.

Подготовка фикстур и выбор браузера

Выберите браузер в UI Cypress перед запуском тестов (Cypress поддерживает Chrome, Edge, Electron и Firefox).

A list of available browsers on Cypress UI testing client.

Создайте фикстуру cypress/fixtures/example.json с тестовыми данными:

{
  "username": "testuser",
  "password": "password123"
}

Фикстуры — это статические тестовые данные, которые удобно переиспользовать в нескольких тестах.

Примеры тестов: cy.request

Cypress предоставляет cy.request для выполнения HTTP-запросов (GET, POST, PUT, DELETE). Ниже — пример полного файла тестов cypress/e2e/user.routes.spec.cy.js.

describe('User Routes', () => {
  it('registers a new user', () => {
    cy.fixture('example').then((testUser) => {
      cy.request({
        method: 'POST',
        url: `${baseUrl}/v1/api/register`,
        body: testUser,
      }).then((response) => {
        expect(response.status).to.eq(201);
        expect(response.body.message).to.eq('User registered successfully');
      });
    });
  });

  it('gets users data and the username matches test data', () => {
    cy.fixture('example').then((expectedUserData) => {
      cy.request({
        method: 'GET',
        url: `${baseUrl}/v1/api/users`,
      }).then((response) => {
        expect(response.status).to.eq(200);
        const username = response.body[0].username;
        expect(username).to.eq(expectedUserData.username);
      });
    });
  });

  it('logs in a user', () => {
    cy.fixture('example').then((loginData) => {
      cy.request({
        method: 'POST',
        url: `${baseUrl}/v1/api/login`,
        body: loginData,
      }).then((response) => {
        expect(response.status).to.eq(200);
      });
    });
  });
});

Примечание: в примерах используется переменная baseUrl. В реальном проекте вместо неё можно использовать относительные пути, если настроен baseUrl в cypress.config.js, например:

cy.request('POST', '/v1/api/register', testUser)

Это сокращает код и делает конфигурацию централизованной.

New test file pop modal on cypress client.

A list of available spec test files on Cypress client.

 Cypress test runner logs showing test logs, including a list of the commands executed along with their status.

Критерии приёмки для API тестов

Критерии приёмки (на уровне тесткейса):

  • Регистрация: ответ 201 и сообщение подтверждения.
  • Получение списка: ответ 200 и соответствие username из фикстуры.
  • Логин: ответ 200 при корректных данных, 401 при неверных.
  • Поведение при ошибках: ответ 500 при непредвиденной ошибке.
  • Идентификация повторных регистраций: при попытке повторной регистрации — предусмотреть поведение и покрыть тестом.

Критерии качества тестов:

  • Тесты детерминированы и не зависят от внешних сервисов.
  • Используются фикстуры и моки для стабилизации данных.
  • Тесты выполняются в CI и завершают процесс сборки при падении критичных сценариев.

Тест-кейсы и критерии приёмки (пример таблицы)

ТестОжидаемый статусКритерий приёмки
POST /v1/api/register с валидными данными201Ответ содержит message: ‘User registered successfully’
GET /v1/api/users после регистрации200Первый пользователь соответствует фикстуре
POST /v1/api/login с валидными данными200Ответ содержит message: ‘Login successful’
POST /v1/api/login с неверным паролем401Ответ содержит message: ‘Invalid credentials’

Чек-листы для ролей

Разделённые по ролям списки задач для успешного API-тестирования.

Developer:

  • Покрыть основные сценарии регистрации, получения пользователей, логина.
  • Обрабатывать ошибки и возвращать корректные HTTP-коды.
  • Хешировать пароли при использовании реальной БД.
  • Добавить логирование и метрики ошибок.

QA инженер:

  • Написать позитивные и негативные тесты.
  • Прогнать тесты в локальной среде и в CI.
  • Проверить сценарии повторной регистрации и граничные значения.
  • Добавить тесты на валидацию входных данных.

DevOps:

  • Интегрировать запуск Cypress в пайплайн CI (headless режим).
  • Обеспечить изолированную среду для тестов (контейнеры или ephemeral окружение).
  • Настроить ретраи/перезапуск для флейки-тестов.

Security engineer:

  • Проверить хранение секретов и передачу паролей по HTTPS.
  • Добавить тесты на авторизацию и доступ к приватным ресурсам.

Методология и мини-план тестирования API

  1. Подготовка окружения: поднять минимально необходимый стек (API + зависимости).
  2. Фикстуры и тестовые данные: центральное хранилище тестовых наборов.
  3. Unit тесты контроллеров и бизнес-логики (Jest/Mocha).
  4. Интеграционные API тесты Cypress (cy.request).
  5. Нагрузочные и перформанс тесты (отдельный инструмент).
  6. Запуск в CI: smoke → интеграция → full-regression.

Совет: отделяйте unit и интеграционные тесты — unit быстрее и даёт локальную гарантию корректности логики, интеграционные обеспечивают совместную работу компонентов.

Когда подход с Cypress может не подойти (контрпримеры)

  • Нагрузочное тестирование и стресс-тесты: Cypress не предназначен для высоконагруженных тестов — используйте k6, Gatling или JMeter.
  • Сложная эмуляция внешних сервисов с нестабильной задержкой: для этих задач лучше применять специализированные моки/песочницы.
  • Тестирование чисто серверных процессов без HTTP-интерфейсов: здесь подходят unit-тесты и фреймворки уровня Jest/Mocha.

Альтернативные подходы

  • Supertest + Jest/Mocha: популярная связка для интеграционных тестов Node.js приложений. Хороша для тестов на уровне HTTP без запуска браузера.
  • Postman / Newman: удобен для ручного тестирования и автоматизации коллекций в CI.
  • Pact/Contract testing: если нужны контракты между командами, стоит подумать о контрактных тестах.

Сравнение:

  • Cypress: отлично для E2E и простых API-интеграций в экосистеме JS.
  • Supertest: легковесно и прямолинейно для интеграций сервера.
  • Postman: удобен для интерфейсного тестирования и обмена коллекциями с командой.

CI/CD: запуск Cypress в headless режиме

Пример npm-скрипта для CI (headless):

"cypress:run": "npx cypress run"

В CI определите шаги:

  • Поднять ephemeral окружение сервера (docker-compose или развертывание).
  • Запустить миграции/фикстуры.
  • Выполнить npx cypress run.
  • Собирать артефакты: видео, логи, скриншоты при падениях.

Безопасность и конфиденциальность

  • Никогда не храните реальные пароли или персональные данные в фикстурах в открытом виде.
  • Для чувствительных данных используйте секреты CI и локальные переменные окружения.
  • В продакшне — всегда HTTPS и проверка сертификатов.

Риск-матрица и смягчающие меры

РискВероятностьВлияниеСмягчение
Флейки-тестыСредняяСреднееПовторные запуски, стабилизация фикстур
Утечка тестовых данныхНизкаяВысокоеХранение секретов в vault, очистка данных
Неправильные ожидания в тестахСредняяСреднееРевью тестов и pair-testing

Примеры расширенных проверок и приёмо-сдаточные тесты

  • Проверить, что при повторной регистрации с тем же username API возвращает корректный код (например, 409) — если так определено в API.
  • Проверить, что список пользователей не содержит пароли в ответе.
  • Тест на время отклика: базовое ожидание, например, ответ приходит менее 500 мс (без выдуманных слепков, ориентируйтесь на реальные SLA).

Советы по устранению ошибок и отладке

  • Включите подробное логирование на сервере и собирайте логи при падениях тестов.
  • Используйте cy.log и console.log в тестах и сервере для трассировки.
  • В CI собирайте скриншоты и видео: Cypress умеет это делать автоматически при падении.

Модель принятия решений при выборе инструмента (Mermaid)

flowchart TD
  A[Нужно ли тестировать HTTP API?] --> B{Нагрузочное тестирование?}
  B -- Да --> C[k6 / Gatling]
  B -- Нет --> D{Нужно ли интегрировать с UI?}
  D -- Да --> E[Cypress]
  D -- Нет --> F{Только Node.js среда?}
  F -- Да --> G[Supertest + Jest]
  F -- Нет --> H[Postman/Newman]

## Совместимость и миграция

- Cypress поддерживает Node.js текущих LTS-версий. При обновлении Node или Cypress проверяйте breaking changes в changelog.
- Для миграции от Supertest к Cypress: адаптируйте тесты с использованием cy.request и учтите особенности асинхронности.

## Короткий playbook: шаги от нуля до CI

1. Создать API и минимальные эндпоинты.
2. Настроить cypress.config.js с baseUrl.
3. Написать фикстуры в cypress/fixtures.
4. Создать e2e тесты в cypress/e2e.
5. Локально запустить node server.js и npx cypress open для отладки.
6. Добавить npx cypress run в CI шаг и собрать артефакты.

## Примеры тестов для граничных случаев

- Пустое тело запроса при регистрации — ожидаем 400 с сообщением о валидации.
- Длинные строки в username и password — проверка лимитов.
- Одновременные запросы регистрации — возможные race conditions.

## Итог и рекомендации

Cypress — мощный инструмент для интеграционных и E2E тестов, который удобно использовать в JavaScript-проектах. Для API тестирования он предоставляет удобный cy.request и интеграцию с браузерной автоматикой. Однако для нагрузочного тестирования и сложной симуляции внешних сервисов лучше выбирать специализированные решения.

Важно: комбинируйте unit-, интеграционные и контрактные тесты, чтобы достичь надёжности и покрыть разные уровни ответственности системы.

Краткие рекомендации:
- Покрывайте основные сценарии (позитив/негатив).
- Используйте фикстуры и моки для детерминированности.
- Интегрируйте тесты в CI и собирайте артефакты при падении.


---

Конец руководства.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство