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 会获取给定值的快照,然后将其与存储在测试文件旁的参考快照文件进行比较。如果两个快照不匹配,测试将失败:这可能意味着代码发生了意外更改,或者需要将参考快照更新为新的正确版本。

使用快照 ​

要创建值的快照,可以使用 expect() API 中的 toMatchSnapshot():

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 键直接更新失败的快照。

或者您可以在 CLI 中使用 --update 或 -u 标志来让 Vitest 更新快照。

bash
vitest -u

文件快照 ​

调用 toMatchSnapshot() 时,所有快照都将存储在格式化的快照文件中。这意味着我们需要转义快照字符串中的某些字符(即双引号 " 和反引号 `)。同时,您可能会失去快照内容的语法高亮(如果它们属于某种语言)。

鉴于此,我们引入了 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 元素提供了默认序列化器。

您可以使用 expect.addSnapshotSerializer API 显式添加自定义序列化器。

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,
}

我们使用 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://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. toThrowErrorMatchingSnapshot 和 toThrowErrorMatchingInlineSnapshot 的默认 Error 快照不同 {#_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` 实例快照 `Error.message`
  // 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