Advanced

Stratégies de test avec Claude Code

Découvrez stratégies de test avec Claude Code. Conseils pratiques et exemples de code inclus.

テスト戦略をClaude Codeで設計・実装する

テストは書いたほうがいいとわかっていても、どこまで書くべきか、何をテストすべきかの判断は難しいものです。Claude Codeを使えば、テストピラミッドに基づいた戦略的なテスト設計と実装を効率的に進められます。

テストピラミッドの実践

> プロジェクトのテスト戦略を提案して。
> テストピラミッドに基づいて、
> 単体テスト、統合テスト、E2Eテストの
> 比率と対象を整理して。
テスト種別比率対象ツール
単体テスト70%ビジネスロジック、ユーティリティVitest
統合テスト20%API、DB連携、コンポーネントVitest + Testing Library
E2Eテスト10%主要ユーザーフローPlaywright

単体テストの自動生成

> src/services/ 以下の全関数の単体テストを作成して。
> 正常系、異常系、境界値をカバーして。
> カバレッジ80%以上を目標に。
// src/services/pricing.ts
export function calculatePrice(
  basePrice: number,
  quantity: number,
  discountRate: number
): number {
  if (quantity < 0) throw new Error("数量は0以上必要です");
  if (discountRate < 0 || discountRate > 1) {
    throw new Error("割引率は0~1の範囲で指定してください");
  }
  const subtotal = basePrice * quantity;
  return Math.round(subtotal * (1 - discountRate));
}

// __tests__/services/pricing.test.ts
import { describe, it, expect } from "vitest";
import { calculatePrice } from "../../services/pricing";

describe("calculatePrice", () => {
  // 正常系
  it("基本価格 × 数量を返す", () => {
    expect(calculatePrice(100, 5, 0)).toBe(500);
  });

  it("割引を適用する", () => {
    expect(calculatePrice(1000, 1, 0.1)).toBe(900);
  });

  it("小数点以下を四捨五入する", () => {
    expect(calculatePrice(333, 3, 0.1)).toBe(899);
  });

  // 境界値
  it("数量0で0を返す", () => {
    expect(calculatePrice(100, 0, 0)).toBe(0);
  });

  it("割引率100%で0を返す", () => {
    expect(calculatePrice(100, 5, 1)).toBe(0);
  });

  // 異常系
  it("負の数量でエラーを投げる", () => {
    expect(() => calculatePrice(100, -1, 0)).toThrow("数量は0以上");
  });

  it("範囲外の割引率でエラーを投げる", () => {
    expect(() => calculatePrice(100, 1, 1.5)).toThrow("割引率は0~1");
    expect(() => calculatePrice(100, 1, -0.1)).toThrow("割引率は0~1");
  });
});

統合テストの生成

APIエンドポイントの統合テストを生成します。

> /api/orders エンドポイントの統合テストを作成して。
> テスト用DBを使って実際のCRUD操作をテスト。
> テスト間でデータが干渉しないように。
import { describe, it, expect, beforeEach, afterAll } from "vitest";
import request from "supertest";
import { app } from "../../app";
import { prisma } from "../../lib/prisma";

describe("Orders API Integration", () => {
  beforeEach(async () => {
    await prisma.order.deleteMany();
    await prisma.user.upsert({
      where: { id: "test-user" },
      update: {},
      create: { id: "test-user", email: "[email protected]", name: "Test" },
    });
  });

  afterAll(async () => {
    await prisma.$disconnect();
  });

  it("POST /api/orders で注文を作成できる", async () => {
    const res = await request(app)
      .post("/api/orders")
      .set("Authorization", "Bearer test-token")
      .send({
        items: [{ productId: "P1", quantity: 2, price: 1000 }],
      });

    expect(res.status).toBe(201);
    expect(res.body.data.id).toBeDefined();
    expect(res.body.data.totalAmount).toBe("2000");
  });

  it("GET /api/orders で注文一覧を取得できる", async () => {
    // Testsデータ作成
    await prisma.order.create({
      data: {
        userId: "test-user",
        totalAmount: 5000,
        status: "confirmed",
      },
    });

    const res = await request(app)
      .get("/api/orders")
      .set("Authorization", "Bearer test-token");

    expect(res.status).toBe(200);
    expect(res.body.data).toHaveLength(1);
  });
});

E2Eテストの生成

主要なユーザーフローをPlaywrightでテストします。

> ユーザー登録からログインまでのE2Eテストを
> Playwrightで作成して。
import { test, expect } from "@playwright/test";

test.describe("ユーザー登録・ログインフロー", () => {
  test("新規ユーザー登録からダッシュボード表示まで", async ({ page }) => {
    // 登録ページにアクセス
    await page.goto("/register");
    await expect(page.getByRole("heading", { name: "新規登録" })).toBeVisible();

    // フォーム入力
    await page.getByLabel("メールアドレス").fill("[email protected]");
    await page.getByLabel("パスワード").fill("SecurePass123");
    await page.getByLabel("パスワード確認").fill("SecurePass123");

    // 登録実行
    await page.getByRole("button", { name: "登録" }).click();

    // ダッシュボードにリダイレクトされる
    await expect(page).toHaveURL("/dashboard");
    await expect(page.getByText("ようこそ")).toBeVisible();
  });

  test("無効なメールアドレスでエラー表示", async ({ page }) => {
    await page.goto("/register");
    await page.getByLabel("メールアドレス").fill("invalid-email");
    await page.getByRole("button", { name: "登録" }).click();

    await expect(page.getByText("有効なメールアドレスを入力")).toBeVisible();
  });
});

テストカバレッジの改善

> テストカバレッジレポートを生成して、
> カバレッジが低いファイルにテストを追加して。
> 80%以上を目標に。
# Claude Codeが実行するコマンド
npx vitest --coverage --run

TDDでのテスト先行開発はTDDとClaude Codeの相性を、CI/CDでのテスト自動実行はCI/CDパイプライン構築ガイドを参照してください。デバッグでのテスト活用はデバッグテクニック完全ガイドもあわせてご覧ください。

Summary

テスト戦略の構築は「何をどのレベルでテストするか」の判断が重要です。Claude Codeにテストピラミッドを意識させて指示すれば、効率的で効果的なテスト体系が構築できます。まずは単体テストから始めて、段階的にカバレッジを広げましょう。

テストフレームワークの詳細はVitest公式ドキュメント、Claude CodeについてはAnthropic公式ドキュメントを参照してください。

#Claude Code #testing #テスト戦略 #Vitest #Playwright