Skip to content
Vitest 1
Main Navigation РуководствоAPIКонфигурацияПродвинутый
1.6.1
0.34.6

Русский

English
简体中文
繁體中文
Español
Français
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Русский

English
简体中文
繁體中文
Español
Français
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Внешний вид

Sidebar Navigation

Руководство

Зачем Vitest

Начало работы

Функциональность

Рабочая область

Интерфейс командной строки

Фильтрация тестов

Репортёры

Покрытие кода

Снапшоты

Мокирование

Тестирование типов

Vitest UI

Режим браузера

In-source тестирование (Тестирование в исходном коде)

Контекст теста

Тестовая среда

Расширение проверок (matchers)

Интеграции с IDE

Отладка

Сравнения с другими тестовыми фреймворками

Руководство по миграции

Распространенные ошибки

Улучшение производительности

API

Справочник по Test API

Mock-функции

Vitest

expect

expectTypeOf

assert

assertType

Конфигурация

Настройка конфигурационного файла Vitest

Настройка Vitest

Содержание страницы

Снапшоты ​

Изучите снапшоты на видеоуроке от Vue School

Снапшот-тесты — это полезный инструмент для проверки стабильности вывода функций.

При использовании снапшотов Vitest создает снимок (snapshot) заданного значения и сравнивает его с эталонным снапшот-файлом, который хранится рядом с тестом. Тест завершится неудачей, если два снапшота не совпадают: это может означать, что изменение является неожиданным, или что эталонный снапшот необходимо обновить до новой версии результата.

Использование снапшотов ​

Чтобы создать снапшот значения, используйте метод toMatchSnapshot() из API expect():

ts
function toUpperCase(str: string) {
  return str;
}
// ---cut---
import { expect, it } from 'vitest';

it('toUpperCase', () => {
  const result = toUpperCase('foobar');
  expect(result).toMatchSnapshot();
});

При первом запуске этого теста Vitest создаст файл снапшота, который будет выглядеть следующим образом:

js
// Vitest Snapshot v1, https://www.getbook.com/ru/book/vitest-1/guide/snapshot

exports['toUpperCase 1'] = '"FOOBAR"';

Файл снапшота следует зафиксировать (commit) вместе с изменениями кода и проверить при ревью. При последующих запусках тестов Vitest будет сравнивать вывод с сохраненным снапшотом. Если они совпадают, тест пройдет успешно. Если они не совпадают, это означает, что Vitest обнаружил ошибку в вашем коде, которую следует исправить, или что реализация изменилась, и снапшот необходимо обновить.

WARNING

При использовании снапшотов с асинхронными параллельными тестами необходимо использовать expect из локального контекста теста, чтобы гарантировать корректное определение теста.

Встроенные снапшоты ​

Вы также можете использовать toMatchInlineSnapshot() для хранения снапшота непосредственно в файле теста.

ts
function toUpperCase(str: string) {
  return str;
}
// ---cut---
import { expect, it } from 'vitest';

it('toUpperCase', () => {
  const result = toUpperCase('foobar');
  expect(result).toMatchInlineSnapshot();
});

Вместо создания отдельного файла снапшота Vitest изменит файл теста, обновив снапшот непосредственно в виде строки:

ts
function toUpperCase(str: string) {
  return str;
}
// ---cut---
import { expect, it } from 'vitest';

it('toUpperCase', () => {
  const result = toUpperCase('foobar');
  expect(result).toMatchInlineSnapshot('"FOOBAR"');
});

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

WARNING

При использовании снапшотов с асинхронными параллельными тестами необходимо использовать expect из локального контекста теста, чтобы гарантировать корректное определение теста.

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

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

В режиме наблюдения (watch mode) можно нажать клавишу u в терминале, чтобы обновить все неудачные снапшоты.

Также можно использовать флаг --update или -u в CLI, чтобы Vitest обновил снапшоты.

bash
vitest -u

Файловые снапшоты ​

При использовании toMatchSnapshot() все снапшоты сохраняются в отформатированном файле .snap. Это означает, что некоторые символы, такие как двойные кавычки " и обратные апострофы ```, должны быть экранированы в строке снапшота. Кроме того, может быть потеряна подсветка синтаксиса для содержимого снапшота (если оно написано на каком-либо языке).

Для решения этой проблемы рекомендуется использовать toMatchFileSnapshot() для сохранения снапшотов непосредственно в отдельных файлах. Это позволяет использовать любые расширения файлов для снапшотов, что делает их более читаемыми и удобными для редактирования.

ts
import { expect, it } from 'vitest';

it('render basic', async () => {
  const result = renderHTML(h('div', { class: 'foo' }));
  await expect(result).toMatchFileSnapshot('./test/basic.output.html');
});

Результат будет сравниваться с содержимым файла ./test/basic.output.html. Файл может быть перезаписан с помощью флага --update.

Снапшоты изображений ​

Также возможно создавать снапшоты изображений с помощью jest-image-snapshot.

bash
npm i -D jest-image-snapshot
ts
test('image snapshot', () => {
  expect(readFileSync('./test/stubs/input-image.png')).toMatchImageSnapshot();
});

Более подробную информацию можно найти в примере examples/image-snapshot.

Пользовательский сериализатор ​

Вы можете добавить собственную логику для изменения способа сериализации ваших снапшотов. Как и Jest, Vitest имеет сериализаторы по умолчанию для встроенных типов JavaScript, элементов HTML, ImmutableJS и элементов React.

Вы можете явно добавить свой собственный сериализатор, используя API expect.addSnapshotSerializer.

ts
expect.addSnapshotSerializer({
  serialize(val, config, indentation, depth, refs, printer) {
    // `printer` — это функция, которая сериализует значение с помощью существующих плагинов.
    return `Pretty foo: ${printer(val.foo, config, indentation, depth, refs)}`;
  },
  test(val) {
    return val && Object.prototype.hasOwnProperty.call(val, 'foo');
  },
});

Мы также поддерживаем параметр snapshotSerializers для неявного добавления пользовательских сериализаторов.

ts
import { SnapshotSerializer } from 'vitest';

export default {
  serialize(val, config, indentation, depth, refs, printer) {
    // `printer` — это функция, которая сериализует значение с помощью существующих плагинов.
    return `Pretty foo: ${printer(val.foo, config, indentation, depth, refs)}`;
  },
  test(val) {
    return val && Object.prototype.hasOwnProperty.call(val, 'foo');
  },
} satisfies SnapshotSerializer;
ts
import { defineConfig } from 'vite';

export default defineConfig({
  test: {
    snapshotSerializers: ['path/to/custom-serializer.ts'],
  },
});

После добавления теста, подобного этому:

ts
test('foo snapshot test', () => {
  const bar = {
    foo: {
      x: 1,
      y: 2,
    },
  };

  expect(bar).toMatchSnapshot();
});

Вы получите следующий снапшот:

Pretty foo: Object {
  "x": 1,
  "y": 2,
}

Для сериализации снапшотов используется библиотека pretty-format от Jest. Подробнее об этом можно прочитать здесь: pretty-format.

Отличия от Jest ​

Vitest предоставляет почти полностью совместимую функциональность снапшотов с Jest с несколькими исключениями:

1. Заголовок комментария в файле снапшота отличается {#_1-comment-header-in-the-snapshot-file-is-different} ​

diff
- // Jest Snapshot v1, https://goo.gl/fbAQLP
+ // Vitest Snapshot v1, https://www.getbook.com/ru/book/vitest-1/guide/snapshot

Это не влияет на функциональность, но может отразиться на diff коммита при переходе с Jest.

2. printBasicPrototype по умолчанию имеет значение false {#_2-printbasicprototype-is-default-to-false} ​

Снапшоты Jest и Vitest основаны на pretty-format. В Vitest значение printBasicPrototype по умолчанию установлено в false, чтобы обеспечить более чистый вывод снапшота, в то время как в Jest <29.0.0 по умолчанию установлено значение true.

ts
import { expect, test } from 'vitest';

test('snapshot', () => {
  const bar = [
    {
      foo: 'bar',
    },
  ];

  // in Jest
  expect(bar).toMatchInlineSnapshot(`
    Array [
      Object {
        "foo": "bar",
      },
    ]
  `);

  // in Vitest
  expect(bar).toMatchInlineSnapshot(`
    [
      {
        "foo": "bar",
      },
    ]
  `);
});

Мы считаем, что это более удобное значение по умолчанию для удобочитаемости и улучшения DX (опыта разработчика). Если вы предпочитаете поведение Jest, вы можете изменить конфигурацию:

ts
// vitest.config.js
export default defineConfig({
  test: {
    snapshotFormat: {
      printBasicPrototype: true,
    },
  },
});

3. Угловая скобка > используется как разделитель вместо двоеточия : для пользовательских сообщений {#_3-chevron-is-used-as-a-separator-instead-of-colon-for-custom-messages} ​

Vitest использует знак 'больше' > как разделитель вместо двоеточия : для повышения удобочитаемости, когда передается пользовательское сообщение во время создания файла снапшота.

Для следующего примера кода теста:

js
test('toThrowErrorMatchingSnapshot', () => {
  expect(() => {
    throw new Error('error');
  }).toThrowErrorMatchingSnapshot('hint');
});

В Jest снапшот будет:

console
exports[`toThrowErrorMatchingSnapshot: hint 1`] = `"error"`;

В Vitest эквивалентный снимок будет выглядеть так:

console
exports[`toThrowErrorMatchingSnapshot > hint 1`] = `[Error: error]`;

4. Снимок Error по умолчанию различается для toThrowErrorMatchingSnapshot и toThrowErrorMatchingInlineSnapshot {#_4-default-error-snapshot-is-different-for-tothrowerrormatchingsnapshot-and-tothrowerrormatchinginlinesnapshot} ​

js
import { expect, test } from 'vitest';
// ---cut---
test('snapshot', () => {
  //
  // in Jest
  //

  expect(new Error('error')).toMatchInlineSnapshot(`[Error: error]`);

  // Jest создает снимок `Error.message` для экземпляров `Error`
  expect(() => {
    throw new Error('error');
  }).toThrowErrorMatchingInlineSnapshot(`"error"`);

  //
  // in Vitest
  //

  expect(new Error('error')).toMatchInlineSnapshot(`[Error: error]`);

  expect(() => {
    throw new Error('error');
  }).toThrowErrorMatchingInlineSnapshot(`[Error: error]`);
});
Pager
Предыдущая страницаПокрытие кода
Следующая страницаМокирование

Выпущено на условиях лицензии MIT.

Авторские права (c) 2024 Mithril Contributors

https://v1.vitest.dev/guide/snapshot

Выпущено на условиях лицензии MIT.

Авторские права (c) 2024 Mithril Contributors