VitestAdvanced Techniques with Claude Code
Learn about vitestadvanced techniques using Claude Code. Practical tips and code examples included.
Vitestで高品質なテストスイートを構築する
VitestはViteベースの高速テストフレームワークです。Jest互換のAPIに加え、TypeScriptのネイティブサポート、HMR対応の監視モードなど、モダンな開発体験を提供します。Claude Codeは複雑なテストシナリオのコード生成に非常に優れています。
高度なモック戦略
Claude Codeにモジュールモックの設計を依頼しましょう。
> 外部APIクライアントのモックを設計して。
> リクエスト・レスポンスの型チェック付き、エラーケースも含めて。
import { describe, it, expect, vi, beforeEach } from "vitest";
import { UserService } from "./user-service";
import { ApiClient } from "./api-client";
// モジュールモック
vi.mock("./api-client", () => ({
ApiClient: vi.fn().mockImplementation(() => ({
get: vi.fn(),
post: vi.fn(),
put: vi.fn(),
delete: vi.fn(),
})),
}));
describe("UserService", () => {
let service: UserService;
let mockClient: ReturnType<typeof vi.mocked<ApiClient>>;
beforeEach(() => {
vi.clearAllMocks();
mockClient = new ApiClient() as any;
service = new UserService(mockClient);
});
it("ユーザー一覧を取得する", async () => {
const mockUsers = [
{ id: "1", name: "Alice", email: "alice@example.com" },
{ id: "2", name: "Bob", email: "bob@example.com" },
];
vi.mocked(mockClient.get).mockResolvedValue({ data: mockUsers });
const result = await service.getUsers();
expect(mockClient.get).toHaveBeenCalledWith("/users");
expect(result).toEqual(mockUsers);
});
it("APIエラー時にカスタム例外をスローする", async () => {
vi.mocked(mockClient.get).mockRejectedValue(
new Error("Network Error")
);
await expect(service.getUsers()).rejects.toThrow("ユーザーの取得に失敗しました");
});
});
パラメータテスト(test.each)
同じロジックを複数のパラメータで検証するパターンです。
describe("バリデーション関数", () => {
it.each([
{ input: "test@example.com", expected: true },
{ input: "user+tag@domain.co.jp", expected: true },
{ input: "invalid-email", expected: false },
{ input: "@no-local.com", expected: false },
{ input: "no-domain@", expected: false },
{ input: "", expected: false },
])("isValidEmail($input) => $expected", ({ input, expected }) => {
expect(isValidEmail(input)).toBe(expected);
});
it.each`
password | minLength | hasUpper | hasNumber | expected
${"Abc12345"} | ${8} | ${true} | ${true} | ${true}
${"abc12345"} | ${8} | ${false} | ${true} | ${false}
${"short"} | ${8} | ${false} | ${false} | ${false}
${"NoNumbers"} | ${8} | ${true} | ${false} | ${false}
`(
"パスワード強度チェック: $password",
({ password, expected }) => {
expect(isStrongPassword(password)).toBe(expected);
}
);
});
カスタムマッチャーの作成
プロジェクト固有のアサーションを定義できます。
// vitest.setup.ts
import { expect } from "vitest";
expect.extend({
toBeWithinRange(received: number, floor: number, ceiling: number) {
const pass = received >= floor && received <= ceiling;
return {
message: () =>
`expected ${received} to be within range ${floor} - ${ceiling}`,
pass,
};
},
toBeValidDate(received: string) {
const date = new Date(received);
const pass = !isNaN(date.getTime());
return {
message: () => `expected "${received}" to be a valid date string`,
pass,
};
},
toMatchApiResponse(received: unknown) {
const pass =
typeof received === "object" &&
received !== null &&
"data" in received &&
"meta" in received;
return {
message: () => `expected value to match API response shape`,
pass,
};
},
});
// 型定義
declare module "vitest" {
interface Assertion<T = any> {
toBeWithinRange(floor: number, ceiling: number): void;
toBeValidDate(): void;
toMatchApiResponse(): void;
}
}
スナップショットテストの活用
コンポーネントやデータ構造のスナップショットテストです。
import { render } from "@testing-library/react";
describe("UserProfile", () => {
it("プロフィールカードが正しくレンダリングされる", () => {
const { container } = render(
<UserProfile
user={{
id: "1",
name: "テストユーザー",
email: "test@example.com",
role: "admin",
}}
/>
);
expect(container).toMatchSnapshot();
});
it("インラインスナップショットでAPIレスポンスを検証", () => {
const response = transformUserResponse(rawData);
expect(response).toMatchInlineSnapshot(`
{
"displayName": "テストユーザー",
"email": "test@example.com",
"isAdmin": true,
}
`);
});
});
テストカバレッジの最適化
// vitest.config.ts
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
coverage: {
provider: "v8",
reporter: ["text", "json", "html", "lcov"],
include: ["src/**/*.{ts,tsx}"],
exclude: [
"src/**/*.d.ts",
"src/**/*.test.{ts,tsx}",
"src/**/*.stories.{ts,tsx}",
"src/types/**",
"src/**/index.ts",
],
thresholds: {
statements: 80,
branches: 75,
functions: 80,
lines: 80,
},
},
setupFiles: ["./vitest.setup.ts"],
environment: "jsdom",
globals: true,
},
});
非同期テストのパターン
タイマーやイベント待機など、非同期処理のテスト手法です。
describe("非同期処理のテスト", () => {
it("デバウンス関数が正しく動作する", async () => {
vi.useFakeTimers();
const fn = vi.fn();
const debounced = debounce(fn, 300);
debounced("a");
debounced("b");
debounced("c");
expect(fn).not.toHaveBeenCalled();
vi.advanceTimersByTime(300);
expect(fn).toHaveBeenCalledTimes(1);
expect(fn).toHaveBeenCalledWith("c");
vi.useRealTimers();
});
it("リトライロジックが正しく動作する", async () => {
const fn = vi
.fn()
.mockRejectedValueOnce(new Error("1回目失敗"))
.mockRejectedValueOnce(new Error("2回目失敗"))
.mockResolvedValue("成功");
const result = await retry(fn, { maxAttempts: 3, delay: 100 });
expect(result).toBe("成功");
expect(fn).toHaveBeenCalledTimes(3);
});
});
Summary
Vitestは高速な実行速度とモダンなAPIにより、テスト開発の体験を大きく向上させます。Claude Codeを活用すれば、モック設計、パラメータテスト、カスタムマッチャーなどの高度なテストパターンも素早く実装可能です。
E2Eテストの実装はPlaywright E2Eテスト実践ガイドを、APIモックの詳細はMSW APIモック活用ガイドを参照してください。Vitest公式ドキュメントも確認しておきましょう。
Level up your Claude Code workflow
50 battle-tested prompt templates you can copy-paste into Claude Code right now.
Free PDF: Claude Code Cheatsheet in 5 Minutes
Key commands, shortcuts, and prompt examples on a single printable page.
About the Author
Masa
Engineer obsessed with Claude Code. Runs claudecode-lab.com, a 10-language tech media with 2,000+ pages.
Related Posts
Getting Started with Claude Code Agent SDK — Build Autonomous Agents Fast
Learn how to build autonomous AI agents with Claude Code Agent SDK. Covers setup, tool definitions, and multi-step execution with practical code examples.
The Complete Guide to Context Management in Claude Code
Learn practical techniques to maximize Claude Code's context window. Covers token optimization, conversation splitting, and CLAUDE.md usage.
Mastering Claude Code Hooks: Auto-Format, Auto-Test, and More
Mastering Claude Code Hooks: Auto-Format, Auto-Test, and More. A practical guide with code examples.