Spec-Zone.ru › Deno 2

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

Тестирование снимков сохраняет результат выполнения вашего кода и при каждом запуске тестов сравнивает его с сохранённой эталонной версией. Вместо того чтобы вручную писать проверку для каждого свойства, вы позволяете тестовому средству один раз записать весь сериализованный результат, а затем оно сообщает об ошибке всякий раз, когда результат меняется. Такой подход идеален, если проверяемое значение велико или его сложно описать вручную (отрисованный HTML, вывод CLI, структура ответа API, объекты ошибок), а также когда ожидаемый результат меняется настолько часто, что поддержка ручных проверок становится обременительной. Встроенное средство запуска тестов Deno поддерживает тестирование снимков с помощью метода t.assertSnapshot контекста теста, без импортов и зависимостей.

Напишите свой первый тест снимка

Контекст теста t, который Deno передаёт каждому тесту, содержит метод assertSnapshot. Он сериализует значение и сравнивает его с эталонным снимком, хранящимся рядом с файлом теста; в качестве ключа снимка используется имя теста:

example_test.ts
Deno.test("isSnapshotMatch", async (t) => {
  const a = {
    hello: "world!",
    example: 123,
  };
  await t.assertSnapshot(a);
});

Пока снимка нет, поэтому при первом запуске его нужно создать. Снимки создаются и обновляются с флагом --update-snapshots (краткая форма — -u):

›_
deno test --update-snapshots

Средство запуска само управляет файлами снимков, поэтому для снимков в расположении по умолчанию не требуются разрешения на чтение или запись. После создания снимка запустите тест обычным способом: он пройдёт, если сериализованное значение по-прежнему совпадает, и завершится с ошибкой, содержащей AssertionError с различиями, если оно изменилось:

›_
deno test

Прочитайте файл снимка

Снимки записываются в каталог __snapshots__ рядом с файлом теста, в файл .snap с именем, соответствующим имени модуля теста. Для приведённого выше примера это файл __snapshots__/example_test.ts.snap:

__snapshots__/example_test.ts.snap
export const snapshot = {};

snapshot[`isSnapshotMatch 1`] = `
{
  example: 123,
  hello: "world!",
}
`;

Каждая запись имеет ключ из имени теста и счётчика, поэтому тест, который вызывает assertSnapshot несколько раз, создаёт isSnapshotMatch 1, isSnapshotMatch 2 и так далее. Значение получается сериализацией ваших данных с помощью Deno.inspect; ключи объектов сортируются по алфавиту. Файлы снимков представляют собой обычный TypeScript, поэтому их легко читать при проверке кода.

Добавляйте файлы снимков в систему контроля версий. Тогда изменения снимков будут проверяться вместе с изменениями кода, которые их вызвали, а каждый, кто получит вашу ветку, сможет запускать проходящие тесты, не создавая снимки заново на своей машине.

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

Этой частью рабочего процесса вы будете пользоваться чаще всего. Если вы намеренно меняете поведение и тесты снимков начинают завершаться с ошибкой или добавляете новые вызовы assertSnapshot, запустите тесты в режиме обновления:

›_
deno test --update-snapshots

Все снимки, не совпадающие с текущим результатом, перезаписываются, отсутствующие снимки создаются, а уже совпадающие остаются без изменений. В сводке запуска указывается количество обновлённых или удалённых снимков.

Перед фиксацией изменений проверьте различия в файлах .snap с помощью git diff. Команда обновления без проблем сохранит ошибки как новый ожидаемый результат, поэтому именно проверка этих различий человеком и придаёт тестам снимков их ценность.

Чтобы попробовать весь процесс на примере выше, замените hello: "world!" на hello: "everyone!", запустите deno test и посмотрите, как тест завершится с ошибкой и покажет различия. Затем запустите deno test --update-snapshots, и файл снимка будет перезаписан в соответствии с новым результатом.

Проверка снимков в CI

В CI нужно проверять снимки, а не обновлять их, поэтому запускайте тесты без --update-snapshots:

.github/workflows/test.yml
name: Test
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: denoland/setup-deno@v2
        with:
          deno-version: v2.x
      - name: Run tests
        run: deno test

Если запрос на включение изменений меняет результат, запуск CI завершится с ошибкой, и автору придётся обновить снимки локально и зафиксировать новые файлы .snap. Тогда проверяющие увидят в различиях запроса на включение изменений точный результат до и после и смогут убедиться, что изменение было намеренным.

Настройка сериализации и расположения снимков

t.assertSnapshot принимает объект параметров вторым аргументом на случай, если значения по умолчанию не подходят:

serializer_test.ts
import { stripAnsiCode } from "jsr:@std/fmt/colors";

Deno.test("Custom Serializer", async (t) => {
  const output = "\x1b[34mHello World!\x1b[39m";
  await t.assertSnapshot(output, {
    serializer: (actual) => stripAnsiCode(actual),
  });
});

Наиболее полезные параметры:

  • serializer: функция, преобразующая значение в строку. Она должна быть детерминированной. Используйте её, чтобы удалять ANSI-коды цвета, заменять временные метки или UUID заполнителями либо удалять конфиденциальные данные до того, как они попадут в файл, добавленный в систему контроля версий.
  • name: переопределяет ключ снимка, которым по умолчанию является имя теста.
  • dir и path: задают расположение файла снимка относительно файла теста. Для пользовательского расположения требуются разрешения на чтение и запись.
  • mode: принудительно задаёт поведение "assert" или "update" для одного вызова независимо от флага --update-snapshots.

Классы могут настраивать собственную сериализацию, реализовав Symbol.for("Deno.customInspect"), поскольку сериализатор по умолчанию построен на основе Deno.inspect.

Снимки с node:test

Если вы пишете тесты с помощью node:test, а не Deno.test, вам также доступна собственная проверка снимков. t.assert.fileSnapshot сериализует значение, при первом запуске записывает его в файл с заданным именем, а при последующих запусках сравнивает с этим файлом:

node_snapshot_test.ts
import { test } from "node:test";

test("matches the saved output", (t) => {
  t.assert.fileSnapshot({ id: 1, name: "ada" }, "./__snapshots__/user.json");
});
документации средства запуска тестов Node.js.

Когда не следует использовать снимки

Тесты снимков проверяют, что результат не изменился, а не то, что он правильный. Они плохо подходят в следующих случаях:

  • Точную проверку легко написать. assertEquals(sum, 3) гораздо лучше описывает замысел, чем снимок 3.
  • Результат недетерминирован. Временные метки, случайные идентификаторы и неупорядоченные коллекции приводят к нестабильным ошибкам, если не нормализовать их с помощью пользовательского сериализатора.
  • Результат слишком велик. Снимки на несколько тысяч строк при проверке принимают не глядя, что лишает их смысла. Вместо этого создавайте снимок нужного фрагмента.
  • Тест должен проверять поведение, а не представление. Проверка отрисованной строки связывает тест с деталями форматирования, которые могут измениться по посторонним причинам.

Хорошее практическое правило: используйте снимки там, где человек может осмысленно проверить записанный результат, а во всех остальных случаях применяйте явные проверки.

Что дальше

  • Обзор тестирования: встроенное средство запуска тестов, проверки, шаги и разрешения.
  • Имитация: шпионы, заглушки и поддельное время для данных, от которых зависят ваши снимки.

Последнее обновление: 25 июня 2026 г.

© 2018–2025 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/runtime/test/snapshots

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API