Storybook の Story オブジェクトを Vitest の Browser Mode だけで、Visual Regression Test(VRT)ができるようになりました。
本記事では、その導入手順をコンパクトに紹介します。
以下のセットアップが完了していることを前提に進めます。
また、以下 2 つの Storybook フレームワークで動作確認済みです。
加えて、この記事も参考になります。
まず、Vitest で Browser Mode を有効にします。
// vitest.config.js
import react from "@vitejs/plugin-react";
// import nextjs from "vite-plugin-storybook-nextjs"; // nextjs-vite を使う場合
import { playwright } from "@vitest/browser-playwright";
import { defineConfig } from "vitest/config";
/*
* @type {import("vitest/config").ViteUserConfigExport}
*/
const baseConfig = {
plugins: [
react(),
// nextjs(),
],
test: {
include: ["src/**/*.test.{ts,tsx}", "src/**/*.spec.{ts,tsx}"],
setupFiles: ["./vitest.setup.js"],
browser: { // 👈 Browser Mode の設定
enabled: true,
provider: playwright(),
headless: true,
instances: [{ browser: "chromium" }],
},
},
};
export default defineConfig(baseConfig);Vitest Browser Mode 向けのセットアップも追加します。
// vitest.setup.js
import "vitest-browser-react";では、サンプルコンポーネントと Story、テストコードを作成していきます。
// ./bubble-text.tsx
type Props = {
text: string;
};
export const BubbleText = ({ text }: Props) => {
return (
<div>{text}</div>
);
};// ./bubble-text.stories.tsx
import type { Meta, StoryObj } from "@storybook/react-vite";
// or
// import type { Meta, StoryObj } from "@storybook/nextjs-vite";
import { BubbleText } from "./bubble-text";
const meta = {
args: {
text: "Hello, World",
},
component: BubbleText,
} satisfies Meta<typeof BubbleText>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {};@storybook/nextjs-vite を使用する場合composeStories で Story オブジェクトをまとめて取得し、
Story.run() → toMatchScreenshot() の流れで VRT できます。
// ./bubble-text.spec.tsx
import { composeStories } from "@storybook/nextjs-vite";
import { describe, expect, it } from "vitest";
import * as stories from "./bubble-text.stories";
const Stories = composeStories(stories);
describe("BubbleText", () => {
it.each(Object.entries(Stories))("should %s snapshot", async (_, Story) => {
// Act
await Story.run();
// Assert
await expect(document.body).toMatchScreenshot();
});
});@storybook/react-vite を使用する場合@storybook/nextjs-vite と同様に、composeStories で Story オブジェクトをまとめて取得し、 render → toMatchScreenshot() の流れで VRT できます。
import { composeStories } from "@storybook/react-vite";
import { describe, expect, it } from "vitest";
import { render } from "vitest-browser-react";
import * as stories from "./bubble-text.stories";
const Stories = composeStories(stories);
describe("BubbleText", () => {
it.each(Object.entries(Stories))("should %s snapshot", async (_, Story) => {
// Act
const { getByTestId } = await render(
<div data-testid="test">
<Story />
</div>,
);
await expect(getByTestId("test")).toMatchScreenshot();
});
});これにより、Storybook と Vitest だけで完結する VRT 環境が構築できました!🎉
-
※ ログイン不要で投稿できます。
※ 同じブラウザから投稿を削除できます。
0
読み込み中...
タグ「フロントエンド」の記事
以下で書いた通り、プロダクトコードを写経したテストコードを削除しました。 "こぶりー" ( https://kobliy.vercel.app/ ) という個人ブログを読むアプリのコードです。 https://silverbirder.gi
最近のお悩みは、Webのソフトウェア開発におけるテストコードが爆増したことにより、 テスト成功による過度な安心感 によって手動確認するのが減っているのかもと思ったりしています。 例えば、Webのフォーム画面に小さな改修があったとして、その修
以下で書いた個人ブログを読むアプリ(個人ブログライブラリ、略して "こぶりー" )をモバイルアプリで開発していました。 https://silverbirder.github.io/blog/contents/20260419/ 審査関連で
2026年05月11日
タグ「テスト」の記事
以下で書いた通り、プロダクトコードを写経したテストコードを削除しました。 "こぶりー" ( https://kobliy.vercel.app/ ) という個人ブログを読むアプリのコードです。 https://silverbirder.gi
業務でWebフロントエンドのテストコードを書く際に、どこに何を書くかというのをざっくりと考えをまとめてみます。 前提 Webアプリケーションのプログラムファイルがツリー構造である前提とします。 tree よくあるフィーチャー単位のフォルダ構
2026年06月05日
個人開発のバイブコーディングでテストコードを書かせているが意味がなかった。 期待する機能をプロンプトで指示しプロダクションコードが出来上がるが、同時にテストコードも書かせていた。 そのテストコードは、プロダクションコードをそのままテストコー