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

快速开始

特性

工作区

命令行界面

测试筛选

报告器

代码覆盖率

快照(Snapshot)

模拟(Mocking)

类型测试

Vitest UI

源码内测试

测试上下文

测试环境

扩展匹配器

IDE 集成

调试

与其他测试运行器的比较

迁移指南

常见错误

Profiling Test Performance

提升性能

页面导航

快照 ​

通过 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://www.getbook.com/zh-cn/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,以确保检测到正确的测试。

更新快照 ​

当接收到的值与快照不匹配时,测试失败并显示它们之间的差异。当快照更改是预期行为时,您可能希望从当前状态更新快照。

在监听模式下,您可以在终端中按 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 '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/zh-cn/book/vitest-1/guide/snapshot

这实际上不会影响功能,但可能会在从 Jest 迁移时影响您的提交差异(commit diff)。

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

我们认为这对于可读性和整体开发者体验(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. 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
上一页代码覆盖率
下一页模拟(Mocking)

基于 MIT 许可证 发布。

版权所有 (c) 2024 Mithril Contributors

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

基于 MIT 许可证 发布。

版权所有 (c) 2024 Mithril Contributors