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

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

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка Unit-тестов для фронтенда (Jest)
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

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

Jest — стандарт unit-тестирования для JavaScript-проектов. Покрывает изолированную логику: утилиты, хуки, редьюсеры, компоненты. Встроен в Create React App, работает с Next.js, Vite.

Настройка

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 },
    },
};

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

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

// src/utils/currency.test.ts
describe('formatCurrency', () => {
    it('formats RUB 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();
    });
});

Тестирование кастомных хуков

// hooks/useCounter.test.ts
import { renderHook, act } from '@testing-library/react';
import { useCounter } from './useCounter';

describe('useCounter', () => {
    it('initializes with given value', () => {
        const { result } = renderHook(() => useCounter(5));
        expect(result.current.count).toBe(5);
    });

    it('increments', () => {
        const { result } = renderHook(() => useCounter(0));
        act(() => result.current.increment());
        expect(result.current.count).toBe(1);
    });

    it('respects max value', () => {
        const { result } = renderHook(() => useCounter(10, { max: 10 }));
        act(() => result.current.increment());
        expect(result.current.count).toBe(10);
    });
});

Моки 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');
});

Coverage и CI

# .github/workflows/test.yml
- name: Run tests
  run: npm test -- --coverage --ci --maxWorkers=2

- name: Upload coverage
  uses: codecov/codecov-action@v3

Срок реализации

Настройка Jest + первые 30–50 тестов для существующего проекта: 3–5 дней.