はじめに
スナップショットテストという単語は聞いたことがありましたが、どういうものかがわからなかったので、調べて実際にやってみました。
スナップショットテストとは
スナップショットテストとは、ある瞬間のプログラムの出力を スナップショット(保存データ) として保存し、コード変更前後で意図しない変化が起きていないかを確認するテストです。
この方法により、大きなオブジェクトや複数行文字列の期待値を手書きせずに管理でき、差分もテキストで確認できます。
用途は、HTML文字列の生成結果、コンポーネントのレンダリング結果(文字列化した出力)、APIレスポンスの形(フィールド増減の検知)などです。
注意事項として、テスト失敗時に -u で無条件に更新すると不具合を正として固定しやすいため、更新前に差分の内容を確認する必要があります。
実際にやってみた
1. セットアップ
以下のコマンドを実行します。
mkdir vitest-snapshot && cd vitest-snapshot
npm init -y
npm install -D vitest typescript
また、package.json に以下のように scripts を登録します。
{
"scripts": {
"test": "vitest run"
}
}
TypeScriptでテストを書く場合は、tsconfig.json を用意します。
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"types": ["vitest/globals"],
"skipLibCheck": true
},
"include": ["test/**/*.ts"]
}
2. テストコードを書く
以下はオブジェクトと文字列のスナップショットテストです。
import { describe, it, expect } from "vitest";
describe("snapshot", () => {
it("オブジェクトをスナップショットにする", () => {
const user_summary = {
id: 123,
name: "Yamada",
roles: ["admin", "editor"],
flags: {
isActive: true,
},
createdAt: "2025-12-15T00:00:00.000Z",
};
expect(user_summary).toMatchSnapshot();
});
it("文字列をスナップショットにする", () => {
const message = [
"Hello snapshot",
"This is multi-line",
"Vitest is fast",
].join("\n");
expect(message).toMatchSnapshot();
});
});
3. 初回実行(スナップショット生成)
以下コマンドを実行します。
npm run test
初回は test/__snapshots__/snapshot.test.ts.snap にファイルが作られます(テストファイルと同階層に __snapshots__ が作成されます)。このファイルが期待値として扱われます。
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`snapshot > オブジェクトをスナップショットにする 1`] = `
{
"createdAt": "2025-12-15T00:00:00.000Z",
"flags": {
"has2fa": false,
"isActive": true,
},
"id": 123,
"name": "Yamada Taro",
"roles": [
"admin",
"editor",
],
}
`;
exports[`snapshot > 文字列をスナップショットにする 1`] = `
"Hello snapshot
This is multi-line
Vitest is fast"
`;
4. 2回目の実行
例えばオブジェクトのスナップショットテストにあるnameに変更を入れます。その後以下のコマンドを実行します。
npm run test
すると、以下のようにテストが失敗します。
- Expected
+ Received
@@ -3,11 +3,11 @@
"flags": {
"has2fa": false,
"isActive": true,
},
"id": 123,
- "name": "Yamada Taro",
+ "name": "Suzuki Ichiro",
"roles": [
"admin",
"editor",
],
}
5. スナップショットを更新する
変更が意図したものの場合は、スナップショットを更新します。
npx vitest -u
# または
npm test -- -u
すると、スナップショットのname部分が先ほど変えた値に変わっています。
まとめ
- スナップショットテストは「出力を保存して、次回以降に差分検知する」テストです
- Vitestでは
toMatchSnapshot()を使うことでスナップショットテストができます