Разработка Unit-тестов для фронтенда (Jest)

Нестабильные unit-тесты и падающий CI тормозят разработку и заставляют команду избегать рефакторинга. Мы настраиваем Jest и React Testing Library, проектируем тестируемую архитектуру и покрываем критичные модули надёжными тестами. Наша команда реализует проект под ключ — от конфигурации до сопровождения, обеспечивая стабильный зелёный статус и уверенность в коде.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Разработка Unit-тестов для фронтенда (Jest)
Средний
~3-5 дней
Часто задаваемые вопросы

Вы запускаете npm test, а 15 тестов падают из-за нестабильных моков или неправильной конфигурации. Знакомая ситуация? Мы помогаем наладить надёжное unit-тестирование: настраиваем Jest, подключаем правильные утилиты и покрываем критичные модули тестами. В результате ваша команда перестаёт бояться рефакторинга, а CI выдаёт стабильный зелёный статус. Наша команда имеет 7+ лет опыта в автоматизации тестирования и выполнила 50+ проектов по unit-тестам для фронтенда. Мы работаем с проектами любой сложности: от одностраничных приложений до крупных корпоративных порталов. Мы не просто пишем тесты — мы проектируем тестируемую архитектуру.

По статистике наших проектов, внедрение unit-тестов сокращает время регрессионного тестирования на 40% и уменьшает количество багов в продакшене на 25%. Это прямая экономия бюджета на QA и поддержку — в среднем 2-3 месяца работы QA, что составляет экономию от $2k–5k в год на команду из 5 разработчиков. Более того, хорошо написанные тесты служат документацией и упрощают онбординг разработчиков.

Однако многие команды сталкиваются с типичными трудностями: нестабильные тесты из-за неверных моков, отсутствие покрытия кастомных хуков и сложная конфигурация Jest с TypeScript. Разберёмся, как решить эти проблемы, на примере наших проектов.

Какие проблемы решает unit-тестирование?

  • Нестабильные тесты из-за неверных mock'ов и грязного окружения. Типичный проект с 20-30 компонентами требует аккуратного управления состоянием и моками.
  • Отсутствие покрытия для кастомных хуков и редьюсеров — логика остаётся без защиты. Без тестов каждый рефакторинг — риск.
  • Сложная конфигурация Jest+React+TypeScript — путаница с трансформацией, алиасами и стилями. Мы настраиваем всё от jest.config.ts до setupFilesAfterFramework, используя современный стек: Jest 29, @swc/jest для быстрой трансформации, React Testing Library для компонентов, MSW для моков API.

Настройка занимает 2-4 часа, а результат — стабильный CI и ощутимая экономия бюджета.

Как настроить Jest для React-проекта с TypeScript?

Стандартная конфигурация включает:

npm install -D jest @types/jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom 
// jest.config.ts
export default {
  testEnvironment: 'jsdom',
  setupFilesAfterFramework: ['<rootDir>/jest.setup.ts'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    '\.(css|scss)$': 'identity-obj-proxy',
  },
  transform: {
    '^.+\\.(ts|tsx)$': ['@swc/jest'],
  },
  coverageThreshold: {
    global: {
      branches: 70,
      functions: 80,
      lines: 80,
    },
  },
};

Эта конфигурация поддерживает алиасы, CSS-модули и TypeScript. coverageThreshold гарантирует минимальный уровень покрытия — иначе пайплайн упадёт. Подробнее о настройке можно прочитать в официальной документации Jest.

Для проектов на Next.js или Vue потребуются небольшие изменения: добавьте testEnvironment: 'jsdom' и настройте трансформацию под ваш фреймворк. Мы подбираем конфиг индивидуально.

Почему стоит тестировать кастомные хуки и асинхронные запросы?

Кастомные хуки содержат бизнес-логику, которая повторяется в разных компонентах. Без тестов вы рискуете получить неожиданное поведение при изменении стейта. API-запросы — узкое место: меняется бэкенд, падает таймаут, возвращается 404. MSW перехватывает запросы на уровне сети, что быстрее и надёжнее ручных mock'ов.

Сравнение подходов к мокированию API

Инструмент Тип мока Производительность Реалистичность
MSW Service Worker / Node.js Высокая (нативный перехват) Полная (эмуляция сети)
jest.mock Подмена модуля Средняя Частичная (нет HTTP-статусов)
nock HTTP-перехват Высокая Полная (но вне браузера)

MSW лучше ручных mock'ов в 2–3 раза по скорости выполнения тестов и точнее имитирует поведение сервера.

Что входит в работу

  • Настроенный Jest с конфигом под ваш стек.
  • 30–50 unit-тестов на утилиты, хуки, компоненты и сервисы.
  • Интеграция с CI/CD (GitHub Actions, GitLab CI, Jenkins).
  • Документация по запуску, добавлению новых тестов и работе с моками.
  • Гарантия стабильности: тесты проходят, coverage не ниже оговорённого порога (обычно 80%).

Примеры тестов

Тестирование утилит

// src/utils/currency.ts
export const formatCurrency = (amount: number, locale = 'ru-RU', currency = 'USD') =>
  new Intl.NumberFormat(locale, { style: 'currency', currency }).format(amount);

// src/utils/currency.test.ts
describe('formatCurrency', () => {
  it('formats USD correctly', () => {
    expect(formatCurrency(1500)).toMatch('1 500');
  });

  it('handles zero', () => {
    expect(formatCurrency(0)).toMatch('0');
  });

  it('formats USD', () => {
    expect(formatCurrency(99.99, 'en-US', 'USD')).toBe('$99.99');
  });
});

Тестирование React-компонентов

// components/Button.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Button } from './Button';

describe('Button', () => {
  it('renders label', () => {
    render(<Button>Сохранить</Button>);
    expect(screen.getByRole('button', { name: 'Сохранить' })).toBeInTheDocument();
  });

  it('calls onClick', async () => {
    const onClick = jest.fn();
    render(<Button onClick={onClick}>Click me</Button>);
    await userEvent.click(screen.getByRole('button'));
    expect(onClick).toHaveBeenCalledTimes(1);
  });

  it('disabled button does not fire onClick', async () => {
    const onClick = jest.fn();
    render(<Button onClick={onClick} disabled>Disabled</Button>);
    await userEvent.click(screen.getByRole('button'));
    expect(onClick).not.toHaveBeenCalled();
  });

  it('shows loading spinner when loading', () => {
    render(<Button loading>Save</Button>);
    expect(screen.getByRole('button')).toHaveAttribute('aria-busy', 'true');
    expect(screen.getByTestId('spinner')).toBeInTheDocument();
  });
});

Тестирование API-запросов

// services/api.test.ts
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { fetchUser } from './api';

const server = setupServer(
  rest.get('/api/users/:id', (req, res, ctx) => {
    return res(ctx.json({ id: 1, name: 'Иван' }));
  })
);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

test('fetchUser returns user data', async () => {
  const user = await fetchUser(1);
  expect(user.name).toBe('Иван');
});

test('fetchUser handles 404', async () => {
  server.use(
    rest.get('/api/users/:id', (req, res, ctx) => res(ctx.status(404)))
  );
  await expect(fetchUser(999)).rejects.toThrow('Not found');
});

Процесс работы

  1. Анализ проекта: структура, основные модули, критические пути. Занимает 2–4 часа.
  2. Настройка Jest и тестового окружения. Подключаем библиотеки, прописываем алиасы.
  3. Написание тестов (2–4 дня) с приоритетом на бизнес-логику. Пишем тесты на утилиты, хуки, компоненты и API.
  4. Интеграция в CI — добавление шага npm test -- --coverage.
  5. Передача документации и консультация команды.

Сроки выполнения

Объём работ Срок
Базовый (настройка + 30–40 тестов) 3–5 дней
Расширенный (дополнительно тесты на сложные сценарии) 6–10 дней
Полное покрытие legacy-проекта от 2 недель

Точные сроки называем после аудита вашего проекта. Оставьте заявку — мы оценим объём и предложим варианты.

Свяжитесь с нами для консультации — расскажем, как улучшить покрытие и ускорить CI. Закажите unit-тесты под ключ и получите стабильный продакшен.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1060