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

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

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

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

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

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

Отладка

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

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

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

Profiling Test Performance

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

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

Снапшоты ​

Изучите снапшоты по видео от 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://www.getbook.com/ru/book/vitest-1/guide/snapshot

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 из локального контекста теста, чтобы убедиться, что обнаружен правильный тест.

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

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

В watch-режиме вы можете нажать клавишу 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 '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,
}

Мы используем Jest'овский pretty-format для сериализации снапшотов. Вы можете прочитать об этом подробнее здесь: 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

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

Мы считаем, что это более разумное значение по умолчанию для читаемости и улучшения developer experience (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';

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) 2024 Mithril Contributors

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

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

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