Skip to content
Vitest 1
Main Navigation GuideAPIConfigAdvanced
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

Appearance

Sidebar Navigation

Guide

Why Vitest

Getting Started

Features

Workspace

CLI

Test Filtering

Reporters

Coverage

Snapshot

Mocking

Testing Types

Vitest UI

Browser Mode

In-source Testing

Test Context

Environment

Extending Matchers

IDE Integration

Debugging

Comparisons

Migration Guide

Common Errors

Improving Performance

API

Test API Reference

Mock Functions

Vi Utility

Expect

ExpectTypeOf

assert

assertType

Config

Config File

Config Reference

On this page

Snapshot ​

Learn Snapshot by video from Vue School

Snapshot tests are a very useful tool whenever you want to make sure the output of your functions does not change unexpectedly.

When using snapshot, Vitest will take a snapshot of the given value, then compares it to a reference snapshot file stored alongside the test. The test will fail if the two snapshots do not match: either the change is unexpected, or the reference snapshot needs to be updated to the new version of the result.

Use Snapshots ​

To snapshot a value, you can use the toMatchSnapshot() from expect() API:

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

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

The first time this test is run, Vitest creates a snapshot file that looks like this:

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

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

The snapshot artifact should be committed alongside code changes, and reviewed as part of your code review process. On subsequent test runs, Vitest will compare the rendered output with the previous snapshot. If they match, the test will pass. If they don't match, either the test runner found a bug in your code that should be fixed, or the implementation has changed and the snapshot needs to be updated.

WARNING

When using Snapshots with async concurrent tests, expect from the local Test Context must be used to ensure the right test is detected.

Inline Snapshots ​

Similarly, you can use the toMatchInlineSnapshot() to store the snapshot inline within the test file.

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

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

Instead of creating a snapshot file, Vitest will modify the test file directly to update the snapshot as a string:

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

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

This allows you to see the expected output directly without jumping across different files.

WARNING

When using Snapshots with async concurrent tests, expect from the local Test Context must be used to ensure the right test is detected.

Updating Snapshots ​

When the received value doesn't match the snapshot, the test fails and shows you the difference between them. When the snapshot change is expected, you may want to update the snapshot from the current state.

In watch mode, you can press the u key in the terminal to update the failed snapshot directly.

Or you can use the --update or -u flag in the CLI to make Vitest update snapshots.

bash
vitest -u

File Snapshots ​

When calling toMatchSnapshot(), we store all snapshots in a formatted snap file. That means we need to escaping some characters (namely the double-quote " and backtick ```) in the snapshot string. Meanwhile, you might lose the syntax highlighting for the snapshot content (if they are in some language).

To improve this case, we introduce toMatchFileSnapshot() to explicitly snapshot in a file. This allows you to assign any file extension to the snapshot file, and making them more readable.

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');
});

It will compare with the content of ./test/basic.output.html. And can be written back with the --update flag.

Image Snapshots ​

It's also possible to snapshot images using jest-image-snapshot.

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

You can learn more in the examples/image-snapshot example.

Custom Serializer ​

You can add your own logic to alter how your snapshots are serialized. Like Jest, Vitest has default serializers for built-in JavaScript types, HTML elements, ImmutableJS and for React elements.

You can explicitly add custom serializer by using expect.addSnapshotSerializer API.

ts
expect.addSnapshotSerializer({
  serialize(val, config, indentation, depth, refs, printer) {
    // `printer` is a function that serializes a value using existing plugins.
    return `Pretty foo: ${printer(val.foo, config, indentation, depth, refs)}`;
  },
  test(val) {
    return val && Object.prototype.hasOwnProperty.call(val, 'foo');
  },
});

We also support snapshotSerializers option to implicitly add custom serializers.

ts
import { SnapshotSerializer } from 'vitest';

export default {
  serialize(val, config, indentation, depth, refs, printer) {
    // `printer` is a function that serializes a value using existing plugins.
    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'],
  },
});

After adding a test like this:

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

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

You will get the following snapshot:

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

We are using Jest's pretty-format for serializing snapshots. You can read more about it here: pretty-format.

Difference from Jest ​

Vitest provides an almost compatible Snapshot feature with Jest's with a few exceptions:

1. Comment header in the snapshot file is different {#_1-comment-header-in-the-snapshot-file-is-different} ​

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

This does not really affect the functionality but might affect your commit diff when migrating from Jest.

2. printBasicPrototype is default to false {#_2-printbasicprototype-is-default-to-false} ​

Both Jest and Vitest's snapshots are powered by pretty-format. In Vitest we set printBasicPrototype default to false to provide a cleaner snapshot output, while in Jest <29.0.0 it's true by default.

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",
      },
    ]
  `);
});

We believe this is a more reasonable default for readability and overall DX. If you still prefer Jest's behavior, you can change your config:

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

3. Chevron > is used as a separator instead of colon : for custom messages {#_3-chevron-is-used-as-a-separator-instead-of-colon-for-custom-messages} ​

Vitest uses chevron > as a separator instead of colon : for readability, when a custom message is passed during creation of a snapshot file.

For the following example test code:

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

In Jest, the snapshot will be:

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

In Vitest, the equivalent snapshot will be:

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

4. default Error snapshot is different for toThrowErrorMatchingSnapshot and 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 snapshots `Error.message` for `Error` instance
  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
Previous pageCoverage
Next pageMocking

Released under the MIT License.

Copyright (c) 2021-Present Vitest Team

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

Released under the MIT License.

Copyright (c) 2021-Present Vitest Team