using-tests について
using-testsは、アプリケーション開発チーム向けのテストワークフロースキルです。Playwright、統合テスト、ユニットテストの選択方法と、並列テストでのデータ分離を説明します。
主な機能
- 01テスト種類の選択ガイド
- 02PlaywrightによるUIテストの例
- 03API統合テストの指針
- 04独立ロジックのユニットテスト
- 05並列テストのデータ分離
- 06テストコマンドとデバッグのヒント
活用シーン
- 01新機能に適したテスト種類の選択
- 02UIフローとAPI動作のテスト
- 03分離されたDBデータでのテスト実行
- 04Playwrightテスト失敗の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ andrelandgraf/ fullstackrecipes --skill using-testsインストール後、Claude Code で/using-testsを入力して読み込まれたか確認します。
詳細
テストの実施
テスト戦略とワークフローです。テストはスイートごとに分離されたデータを使って並列実行されます。UI には Playwright、API には統合テスト、ロジックにはユニットテストを優先してください。
テスト戦略
テストの種類を決める際は、次の優先順位に従ってください。
- Playwright テスト(ブラウザー) - ほとんどの機能で推奨
- 統合テスト(API) - Playwright が現実的でない場合
- ユニットテスト(純粋関数) - 複雑で独立したロジックに限る
テストの種類の使い分け
Playwright テスト(デフォルトの選択肢)
次の要素が機能に含まれる場合は、Playwright テストを作成してください。
- ユーザー操作(クリック、入力、ナビゲーション)
- 視覚的なフィードバック(トースト、読み込み状態、エラーメッセージ)
- フォームの送信とバリデーション
- 複数ステップの UI フロー
- 保護されたルートとリダイレクト
- アクセシビリティの動作
Playwright でのテストに最適な機能の例:
- エラー処理を含むサインインフロー
- 確認ダイアログを含むチャットの作成と削除
- テーマの切り替え
- フォームのバリデーションメッセージ
- ページ間のナビゲーション
統合テスト
次の場合は、統合テストを作成してください。
- API のレスポンスを直接テストする場合(ステータスコード、JSON 構造)
- 操作後のデータベースの状態を検証する場合
- UI を使わずにサーバー側のロジックをテストする場合
- シナリオに対して Playwright が遅すぎる、または複雑すぎる場合
統合テストに最適な機能の例:
- API ルートが正しいステータスコードを返す
- ユーザー作成によってデータベースが正しく更新される
- サインイン時にセッションクッキーが設定される
- 保護された API ルートが 401/403 を返す
ユニットテスト
次の場合に限り、ユニットテストを作成してください。
- 複雑なロジックを含む純粋関数をテストする場合
- エッジケースが多いコードをテストする場合
- 型の絞り込みとエラーメッセージをテストする場合
- 関数に外部依存関係がない場合
ユニットテストに最適な機能の例:
- アサーションヘルパー
- 設定スキーマのバリデーション
- データ変換関数
- ユーティリティ関数
テストの実行
すべてのテストは、1 時間後に自動削除される分離された Neon データベースブランチに対して実行されます。
bun run test # All tests with isolated Neon branch
bun run test:playwright # Browser tests only
bun run test:integration # Integration tests only
bun run test:unit # Unit tests only
フォルダー構成
src/
├── lib/
│ ├── common/
│ │ ├── assert.ts
│ │ └── assert.test.ts # Unit test (co-located)
│ └── config/
│ ├── schema.ts
│ └── schema.test.ts # Unit test (co-located)
tests/
├── integration/
│ ├── llms.test.ts # Integration test
│ ├── r.test.ts
│ ├── mcp/
│ │ └── route.test.ts
│ └── recipes/
│ └── [slug]/
│ └── route.test.ts
└── playwright/
├── auth.spec.ts # Playwright test
├── chat.spec.ts
├── home.spec.ts
└── lib/
└── test-user.ts # Playwright-specific helpers
新機能のテスト作成
ステップ 1:テストの種類を決める
「ユーザーは、この機能が動作することをどのように確認するか?」と考えてください。
- UI を通じて確認する場合 → Playwright テスト
- API 呼び出しを通じて確認する場合 → 統合テスト
- 関数を直接呼び出して確認する場合 → ユニットテスト
ステップ 2:テストファイルを作成する
Playwright テスト: tests/playwright/{feature}.spec.ts
import { test, expect } from "@playwright/test";
test.describe("Feature Name", () => {
test("should do expected behavior", async ({ page }) => {
await page.goto("/feature");
// Test implementation
});
});
統合テスト: tests/integration/{feature}.test.ts
API ルートの場合は、より高速で信頼性の高いテストを行うため、ハンドラーを直接インポートしてください。
import { describe, it, expect } from "bun:test";
import { GET } from "@/app/api/feature/route";
describe("GET /api/feature", () => {
it("should return expected response", async () => {
const response = await GET();
expect(response.status).toBe(200);
const data = await response.json();
expect(data.value).toBeDefined();
});
});
ユニットテスト: src/lib/{domain}/{file}.test.ts(同じディレクトリに配置)
import { describe, it, expect } from "bun:test";
import { myFunction } from "./my-file";
describe("myFunction", () => {
it("should do expected behavior", () => {
expect(myFunction()).toBe("expected");
});
});
テストデータの管理
データベースの分離
テストは分離された Neon ブランチに対して実行されます。各テスト実行では、次の処理が行われます。
- スキーマのみを含む新しいブランチを作成する
- そのブランチに対してテストを実行する
- 1 時間後にブランチを自動削除する
これにより、テストが本番データに干渉することを防ぎます。
並列テストの分離
テストはデフォルトで並列実行されます。競合を避けるため、各テストスイートでは独自のテストデータを使用する必要があります。
- 異なるテストユーザー - 各 spec ファイルで、異なるメールアドレスを持つ一意のユーザーを作成してください
- 異なるリソース - チャットやセッションなどを作成するテストでは、共有状態に依存しないでください
- クリーンアップ不要 - ブランチの TTL により自動的にクリーンアップされます
// auth.spec.ts - uses auth-specific test user
const testUser = await createTestUser({
email: `auth-test-${uuid}@example.com`,
});
// chat.spec.ts - uses chat-specific test user
const testUser = await createTestUser({
email: `chat-test-${uuid}@example.com`,
});
グローバルな状態や、ほかのテストで特定のデータベース内容が存在することを前提とするパターンは避けてください。
よくあるパターン
保護されたルートのテスト(Playwright)
test("should redirect unauthenticated user", async ({ page }) => {
await page.goto("/protected-page");
await expect(page).toHaveURL(/sign-in/);
});
エラー状態のテスト(Playwright)
test("should show error for invalid input", async ({ page }) => {
await page.goto("/form");
await page.getByRole("button", { name: /submit/i }).click();
await expect(page.getByText(/error|required/i)).toBeVisible({
timeout: 5000,
});
});
API レスポンスのテスト(統合テスト)
テストをより簡潔にするため、ルートハンドラーを直接インポートしてください。
import { GET } from "@/app/api/endpoint/route";
it("should return 200 for valid request", async () => {
const response = await GET();
expect(response.status).toBe(200);
});
失敗したテストのデバッグ
Playwright
bunx playwright test --headed # Watch browser
bunx playwright test --debug # Step through test
bunx playwright show-report # View HTML report
統合テスト/ユニットテスト
bun test --only "test name" # Run single test
bun test --watch # Re-run on changes
テスト成果物の確認
失敗した Playwright テストでは、スクリーンショットとトレースが test-results/ に保存されます。CI が失敗した場合は、このフォルダーを確認してください。