Снапшот-тесты

Урок объясняет снапшот-тесты Jest: что это, как работает обновление и где их уместно применять.

Снапшот-тест сохраняет «слепок» результата при первом запуске и потом сравнивает с ним при каждом прогоне.

Как это работает

Матчер toMatchSnapshot() при первом запуске сериализует значение (объект, разметку компонента) и записывает в файл .snap. При следующих запусках Jest сравнивает текущий результат с сохранённым. Отличается — тест падает и показывает разницу.

test('форма сериализации профиля стабильна', () => {
  const profile = buildProfile({ id: 1, name: 'Аня' });
  expect(profile).toMatchSnapshot();
});

В соседнем __snapshots__/file.test.js.snap появится сохранённый слепок.

Обновление снапшотов

Если изменение ожидаемое (вы намеренно поменяли формат), снапшоты обновляют:

npx jest --updateSnapshot
# короткая форма
npx jest -u

Идея сравнения слепков на чистом JS

Под капотом снапшот — это сравнение сериализованных строк. Покажем механику:

function serialize(obj) {
  return JSON.stringify(obj, null, 2);
}

// "сохранённый" снапшот
const saved = serialize({ id: 1, name: 'Аня', role: 'user' });

// результат текущего запуска
const current = serialize({ id: 1, name: 'Аня', role: 'admin' });

if (saved === current) {
  console.log('\u2713 снапшот совпал');
} else {
  console.log('\u2717 снапшот изменился:');
  console.log('было role: user, стало role: admin');
}

Вывод:

✗ снапшот изменился:
было role: user, стало role: admin

Точно так же Jest хранит сериализованный слепок и при расхождении показывает diff. Разница лишь в том, что Jest умеет красиво сериализовать React-компоненты и сложные структуры.

Плюсы и минусы

ПлюсыМинусы
быстро покрыть большой выводлегко обновить вслепую (-u) и «узаконить» баг
ловят неожиданные изменения разметкибольшие снапшоты нечитаемы в ревью
мало кода в тестене выражают намерение («что именно важно»)

Когда применять

  • Хорошо: небольшой стабильный вывод (сериализация, конфиг, маленький компонент).
  • Осторожно: большие компоненты и часто меняющаяся разметка — снапшоты станут шумом.
  • Правило: ревьюйте .snap как обычный код и не обновляйте вслепую.

Итог

  • Снапшот сохраняет слепок результата и сравнивает с ним в дальнейшем.
  • Обновление — jest -u, но только осознанно.
  • Плюс: быстро и широко; минус: легко «узаконить» баг и нечитаемость.
  • Лучше для небольшого стабильного вывода; .snap нужно ревьюить.
Проверьте себя
1. Что делает toMatchSnapshot() при первом запуске?
AСразу падает
BСохраняет слепок результата в .snap для будущих сравнений
CУдаляет старые тесты
DЗапускает покрытие
2. В чём главная опасность снапшот-тестов?
AОни слишком медленные
BИх легко обновить вслепую (jest -u) и тем самым «узаконить» баг
CОни не работают с объектами
DОни требуют сети
3. Для какого вывода снапшоты подходят лучше всего?
AДля огромных часто меняющихся компонентов
BДля небольшого стабильного вывода вроде сериализации или конфигурации
CДля асинхронных запросов к сети
DДля измерения скорости
Поддержать проект