Как протестировать JS?

Тестирование JavaScript‑кода — ключевой этап разработки, позволяющий выявлять ошибки до выхода продукта в продакшн. Разберём основные подходы, инструменты и практические шаги.

Типы тестирования JS

  1. Модульное (unit‑тестирование)
    Проверка отдельных функций/модулей в изоляции.
    Пример: тест функции сложения двух чисел.
  2. Интеграционное
    Проверка взаимодействия между модулями.
    Пример: тест цепочки «форма → валидация → API‑запрос».
  3. Функциональное (end‑to‑end, E2E)
    Тестирование пользовательских сценариев целиком.
    Пример: имитация оформления заказа на сайте.
  4. Тестирование производительности
    Анализ скорости, нагрузки, памяти.
  5. Тестирование доступности (a11y)
    Проверка соответствия стандартам WCAG.

Основные инструменты

1. Jest (рекомендуется для старта)

Особенности:

  • Всё в одном: запуск, моки, отчёты, покрытие кода.
  • Простая настройка.
  • Поддержка TypeScript.

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

// sum.js
function sum(a, b) {
  return a + b;
}
module.exports = sum;

// sum.test.js
const sum = require('./sum');

test('складывает 1 + 2 и получает 3', () => {
  expect(sum(1, 2)).toBe(3);
});

Запуск:

npm install --save-dev jest
npx jest

2. Mocha + Chai

Mocha — фреймворк для запуска тестов.
Chai — библиотека утверждений (assertions).

Пример:

const { expect } = require('chai');

describe('Функция сложения', () => {
  it('должна возвращать 3 для 1 + 2', () => {
    expect(sum(1, 2)).to.equal(3);
  });
});

Установка:

npm install --save-dev mocha chai

3. Cypress (для E2E)

Особенности:

  • Тестирование реального браузера.
  • Визуальный интерфейс.
  • Автоматическое ожидание элементов.

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

it('должен отображать заголовок', () => {
  cy.visit('http://localhost:3000');
  cy.contains('Добро пожаловать');
});

Пошаговая инструкция по тестированию

Шаг 1. Подготовка проекта

  1. Создайте package.json:
   npm init -y
  1. Установите тестовый фреймворк (например, Jest):
   npm install --save-dev jest
  1. Добавьте скрипт в package.json:
   "scripts": {
     "test": "jest"
   }

Шаг 2. Написание первого теста

  1. Создайте файл example.test.js.
  2. Импортируйте тестируемую функцию.
  3. Напишите тест с test() или it().
  4. Используйте expect() с подходящими методами:
  • .toBe() — строгое равенство.
  • .toEqual() — сравнение объектов.
  • .toContain() — проверка наличия элемента в массиве.
  • .toHaveBeenCalled() — проверка вызова функции.

Шаг 3. Запуск тестов

npm test

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

npx jest example.test.js

Шаг 4. Анализ результатов

  • Зелёный — все тесты пройдены.
  • Красный — ошибки (смотрите детали в консоли).
  • Покрытие кода (если включено): процент протестированных строк.

Шаг 5. Автоматизация

  1. Настройте хуки Git (pre-commit), чтобы тесты запускались перед каждым коммитом.
  2. Интегрируйте тесты в CI/CD (GitHub Actions, GitLab CI).

Лучшие практики

  1. Пишите тесты до кода (TDD)
    Сначала опишите ожидаемое поведение, потом реализуйте логику.
  2. Тестируйте граничные случаи
  • Пустые значения.
  • Крайние числа (Number.MAX_VALUE).
  • Ошибки ввода.
  1. Используйте моки
    Изолируйте тесты от внешних зависимостей (API, базы данных):
   jest.mock('./api', () => ({
     getData: jest.fn(() => Promise.resolve({ id: 1 }))
   }));
  1. Следите за читаемостью
  • Названия тестов должны описывать поведение:
    javascript test('не позволяет отправить форму без email', () => {...});
  1. Обновляйте тесты при рефакторинге
    Тесты — документация кода. Они должны соответствовать текущей логике.
  2. Комбинируйте типы тестов
  • 70% — модульные.
  • 20% — интеграционные.
  • 10% — E2E.

Дополнительные инструменты

  • ESLint — проверка стиля кода.
  • Prettier — автоматическое форматирование.
  • Husky — настройка хуков Git.
  • Allure Report — визуализация результатов тестов.

Пример комплексного теста (Jest)

test('обработка формы регистрации', () => {
  const userData = { email: 'test@example.com', password: '123' };

  // Мокируем API
  jest.spyOn(api, 'register').mockResolvedValue({ success: true });

  // Вызываем функцию
  const result = await registerUser(userData);

  // Проверяем результат
  expect(result.success).toBe(true);
  expect(api.register).toHaveBeenCalledWith(userData);
});

Итог:

  1. Начните с Jest для модульных тестов.
  2. Используйте Cypress для E2E.
  3. Автоматизируйте запуск тестов.
  4. Поддерживайте баланс между типами тестов.
  5. Обновляйте тесты вместе с кодом.