Skip to content
Vitest 3
Main Navigation Руководство & APIКонфигурацияРежим браузераРасширенный API
3.2.0
2.1.9
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

API

Справочник по API тестирования

Мок-функции

Vi

expect

expectTypeOf

assert

assertType

Руководство

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

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

Тестовые проекты

Средства отчётности

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

Снапшот-тестирование

Мокирование

Параллелизм

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

Vitest UI

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

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

Аннотации тестов

Среда тестирования

Расширение матчеров

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

Отладка

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

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

Миграция на Vitest 3.0

Миграция с Jest

Производительность

Профилирование производительности тестов

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

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

Расширенный API

Сравнение с другими тестовыми раннерами

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

Снапшот-тестирование ​

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

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

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

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

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

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

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

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

js
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

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

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

WARNING

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

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

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

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

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

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

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

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

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

WARNING

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

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

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

В режиме наблюдения вы можете нажать клавишу 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();
});

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

Вы можете добавить свою собственную логику для изменения способа сериализации ваших снапшотов. Как и 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 'vitest/config';

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://vitest.dev/guide/snapshot.html

Это не влияет на функциональность, но может привести к различиям в коммите при миграции с 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',
    },
  ];

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

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

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

ts
import { defineConfig } from 'vitest/config';

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'

test('snapshot', () => {
  // в Jest и Vitest
  expect(new Error('error')).toMatchInlineSnapshot(`[Error: error]`)

  // Jest создает снапшот `Error.message` для экземпляра `Error`
  // Vitest выводит то же значение, что и при использовании toMatchInlineSnapshot
  expect(() => {
    throw new Error('error')
  }).toThrowErrorMatchingInlineSnapshot(`"error"`) 
  }).toThrowErrorMatchingInlineSnapshot(`[Error: error]`) 
})
Pager
Предыдущая страницаПокрытие кода
Следующая страницаМокирование

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

Авторские права (c) 2021-Present Vitest Team

https://vitest.dev/guide/snapshot

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

Авторские права (c) 2021-Present Vitest Team