Jest: snapshot тесты

Snapshot-тест сериализует вывод функции или компонента в файл и при повторном запуске сравнивает с сохранённым снимком — любое изменение структуры вызывает падение теста.

Зачем нужно

Snapshot-тесты дешевле в написании, чем полноценные assertions для каждого поля. Они хорошо ловят непреднамеренные изменения в рендере компонентов, JSON-ответах API или строковом выводе функций. Особенно полезны при рефакторинге — убеждают, что вывод не изменился.

Где используется

  • Тестирование React/Vue/Angular компонентов (HTML-структура)
  • Фиксация формата JSON-ответов утилитарных функций
  • Тестирование шаблонов email или документов
  • Быстрое покрытие legacy-кода без понимания деталей реализации

Основной контент

Первый запуск — создание снимка

// Button.test.jsx
import { render } from '@testing-library/react';
import { Button } from './Button';

test('Button рендерится корректно', () => {
  const { container } = render(<Button label="Click me" />);
  expect(container).toMatchSnapshot;
});

При первом запуске Jest создаёт файл __snapshots__/Button.test.jsx.snap:

// Jest Snapshot v1
exports[`Button рендерится корректно 1`] = `
<div>
  <button class="btn">
    Click me
  </button>
</div>
`;

Обновление снимков

# Если изменение намеренное — обновляем снимки
npx jest --updateSnapshot
# или
npx jest -u

Inline snapshots

test('форматирует дату', () => {
  expect(formatDate(new Date('2024-01-15'))).toMatchInlineSnapshot(
    `"15 января 2024"`
  );
});

Inline-снимки хранятся прямо в тест-файле — удобнее для маленьких значений.

Snapshot для чистых функций

test('сериализует конфиг', () => {
  const config = buildConfig({ env: 'production', port: 3000 });
  expect(config).toMatchSnapshot;
});

Частичные снимки (asymmetric matchers)

test('ответ API содержит нужные поля', () => {
  expect(apiResponse).toMatchSnapshot({
    id: expect.any(Number),       // id меняется — игнорируем значение
    createdAt: expect.any(String), // дата меняется
    name: 'Alice',                 // name фиксируем
  });
});

Частые ошибки

  • Коммит устаревших снимков — разработчик запускает --updateSnapshot не глядя и фиксирует сломанную структуру; всегда проверяй diff снимков в PR
  • Огромные снимки — скрывают реальные изменения в море HTML; предпочитай точечные assertions для ключевых свойств
  • Снимки динамических данных — timestamp, id, random — без asymmetric matchers снимок будет падать на каждом запуске
  • Snapshot как замена assertions — снимок не объясняет, что именно должно быть; дополняй обычными expect

Связанные темы

Ресурсы