Skip to content
Vitest 1
Main Navigation 指南API配置高級
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 整合支援

偵錯

與其他測試執行器的比較

遷移指南

常見錯誤

提升效能

API

測試 API 參考文件

模擬函數

Vi

expect

expectTypeOf

assert

assertType

配置

管理 Vitest 配置文件

配置 Vitest

本頁導覽

快照 ​

透過 Vue School 的影片課程學習快照測試

當您想要確保函式的輸出不會意外變更時,快照測試會是一個非常有用的工具。

使用快照時,Vitest 會取得給定值的快照,然後將其與儲存在測試程式碼旁的參考快照檔案進行比較。如果兩個快照不符,測試將會失敗:這表示變更是非預期的,或者需要將參考快照更新為結果的新版本。

使用快照 ​

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

ts
function toUpperCase(str: string) {
  return str;
}
// ---cut---
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,以確保偵測到正確的測試。

內嵌快照(Inline Snapshots) ​

同樣地,您可以使用 toMatchInlineSnapshot() 將快照直接儲存在測試檔案中。

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

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

Vitest 不會建立快照檔案,而是會直接修改測試檔案,將快照更新為字串:

ts
function toUpperCase(str: string) {
  return str;
}
// ---cut---
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

檔案快照(File Snapshots) ​

當呼叫 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 標誌寫回。

圖片快照(Image Snapshots) ​

也可以使用 jest-image-snapshot 對圖片進行快照。

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

您可以在 examples/image-snapshot 範例中了解更多資訊。

自訂序列化器 ​

您可以添加自己的邏輯來修改快照的序列化方式。與 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',
    },
  ];

  // in Jest
  expect(bar).toMatchInlineSnapshot(`
    Array [
      Object {
        "foo": "bar",
      },
    ]
  `);

  // in 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 使用 Chevron > 作為分隔符號,而非冒號 :,以提高可讀性。

對於以下範例測試程式碼:

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';
// ---cut---
test('snapshot', () => {
  //
  // in Jest
  //

  expect(new Error('error')).toMatchInlineSnapshot(`[Error: error]`);

  // Jest 對 `Error` 實例進行 `Error.message` 快照
  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
上一頁覆蓋率
下一頁模擬(Mocking)

以 MIT 授權條款 發布。

版權所有 (c) 2024 Mithril Contributors

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

以 MIT 授權條款 發布。

版權所有 (c) 2024 Mithril Contributors