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

開始使用

功能特性

工作區

命令列界面

測試過濾器

報告器

覆蓋率

快照

模擬(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-tw/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-tw/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",
      },
    ]
  `);
});

我們認為此預設值能提升可讀性與整體開發體驗。如果您仍然喜歡 Jest 的行為,您可以更改您的設定:

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

3. 自訂訊息使用 Chevron > 作為分隔符,而不是冒號 : {#_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