REST API с Express

Для работы с Puppeteer и тестированием REST API на базе Express необходимо создать Node.js-проект и установить зависимости:

mkdir puppeteer-express
cd puppeteer-express
npm init -y
npm install express puppeteer axios jest
  • express — для создания REST API.
  • puppeteer — для автоматизации браузера и тестирования фронтенд-взаимодействий.
  • axios — для HTTP-запросов к API.
  • jest — для организации тестов.

Создание структуры проекта:

puppeteer-express/
├── src/
│   ├── server.js
│   └── routes/
│       └── users.js
├── tests/
│   └── api.test.js
└── package.json

Создание REST API на Express

Файл src/server.js:

const express = require(&
const app = express();
const usersRouter = require('./routes/users');

app.use(express.json());
app.use('/users', usersRouter);

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

module.exports = app;

Файл src/routes/users.js:

const express = require('express');
const router = express.Router();

let users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
];

// Получение всех пользователей
router.get('/', (req, res) => {
  res.json(users);
});

// Получение пользователя по ID
router.get('/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) return res.status(404).json({ message: 'User not found' });
  res.json(user);
});

// Создание нового пользователя
router.post('/', (req, res) => {
  const { name } = req.body;
  if (!name) return res.status(400).json({ message: 'Name is required' });
  const newUser = { id: users.length + 1, name };
  users.push(newUser);
  res.status(201).json(newUser);
});

// Обновление пользователя
router.put('/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) return res.status(404).json({ message: 'User not found' });
  user.name = req.body.name || user.name;
  res.json(user);
});

// Удаление пользователя
router.delete('/:id', (req, res) => {
  const index = users.findIndex(u => u.id === parseInt(req.params.id));
  if (index === -1) return res.status(404).json({ message: 'User not found' });
  users.splice(index, 1);
  res.status(204).send();
});

module.exports = router;

Основы тестирования REST API с Puppeteer

Хотя Puppeteer предназначен для тестирования браузерного взаимодействия, его можно сочетать с API-запросами для интеграционных сценариев. Puppeteer позволяет эмулировать реальный браузер, что полезно для проверки работы фронтенда с REST API.

Пример интеграционного теста с использованием Puppeteer и Jest:

const puppeteer = require('puppeteer');
const axios = require('axios');
const app = require('../src/server');

let server;
beforeAll(() => {
  server = app.listen(4000);
});

afterAll(() => {
  server.close();
});

test('Создание и отображение нового пользователя через фронтенд', async () => {
  // Создание пользователя через API
  const newUser = { name: 'Charlie' };
  const response = await axios.post('http://localhost:4000/users', newUser);
  expect(response.status).toBe(201);
  expect(response.data.name).toBe('Charlie');

  // Проверка через Puppeteer, эмулируя фронтенд
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.goto('http://localhost:4000/users');
  const content = await page.evaluate(() => document.body.innerText);

  expect(content).toContain('Charlie');

  await browser.close();
});

Ключевые моменты:

  • Puppeteer открывает браузер и позволяет взаимодействовать с элементами страницы.
  • Axios используется для подготовки данных и отправки прямых API-запросов.
  • Jest управляет тестами и предоставляет функции beforeAll и afterAll для старта и остановки сервера.

Эмуляция фронтенда и REST API

Для тестирования можно создать простую HTML-страницу, которая запрашивает данные API и отображает их:

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Пользователи</title>
</head>
<body>
<ul id="users"></ul>
<script>
fetch('http://localhost:3000/users')
  .then(res => res.json())
  .then(users => {
    const list = document.getElementById('users');
    users.forEach(u => {
      const li = document.createElement('li');
      li.textContent = u.name;
      list.appendChild(li);
    });
  });
</script>
</body>
</html>

Такой подход позволяет:

  • Проверить корректность получения данных через API.
  • Убедиться, что фронтенд правильно отображает информацию.
  • Интегрировать Puppeteer для автоматизации кликов, форм и визуальной проверки.

Автоматизация сценариев с Puppeteer

Основные операции Puppeteer для тестирования REST API через фронтенд:

  1. Запуск браузера и открытие страницы:
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('http://localhost:3000');
  1. Получение и проверка контента страницы:
const content = await page.$eval('#users', el => el.innerText);
expect(content).toContain('Alice');
  1. Ввод данных в формы и отправка запросов:
await page.type('#username', 'David');
await page.click('#submit');
await page.waitForSelector('#users li:last-child');
const updatedContent = await page.$eval('#users', el => el.innerText);
expect(updatedContent).toContain('David');
  1. Закрытие браузера:
await browser.close();

Интеграция с Jest и CI

Для запуска тестов в автоматизированной среде рекомендуется:

  • Использовать headless-режим Puppeteer (headless: true).
  • Настраивать порты сервера через переменные окружения.
  • Применять beforeAll и afterAll для поднятия и остановки Express-сервера.
  • Разделять unit-тесты API и интеграционные тесты с Puppeteer.

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