Skip to content

テスティング戦略

Vitest + React Testing Library + Playwrightを採用

日付: 2025-01-06

ステータス

2025-01-06 承認済み

コンテキスト

ぷよぷよゲームの品質保証として以下のテストが必要:

  • 単体テスト(ドメインロジック、コンポーネント)
  • 統合テスト(コンポーネント間連携)
  • E2Eテスト(ユーザーシナリオ)
  • TDD開発サイクルのサポート

候補:

  1. Vitest + React Testing Library + Playwright
  2. Jest + React Testing Library + Cypress
  3. Jest + Enzyme + Puppeteer
  4. Vitest のみ

決定

Vitest + React Testing Library + Playwright を採用する

理由

Vitest:

  • Viteとの高速統合
  • ESM ネイティブサポート
  • Jestとの高い互換性
  • TypeScript の完全サポート
  • 優れたパフォーマンス

React Testing Library:

  • ベストプラクティスに基づくテストアプローチ
  • アクセシビリティ重視のAPIデザイン
  • 実際のユーザー体験に近いテスト
  • 優秀なコミュニティサポート

Playwright:

  • クロスブラウザテスト対応
  • 信頼性の高いE2Eテスト
  • 優れたデバッグ機能
  • CI/CD統合の容易さ

他の候補を除外した理由:

  • Jest: Viteとの統合が複雑
  • Enzyme: 実装詳細に依存しがち
  • Cypress: Playwrightより制限が多い

影響

ポジティブな影響

  • 高速実行: Vitestの最適化によるテスト実行速度向上
  • 信頼性: Playwrightの安定したE2Eテスト
  • 保守性: React Testing Libraryのベストプラクティス
  • 開発体験: Hot reloadによる高速フィードバック

ネガティブな影響

  • 学習コスト: 複数ツールの習得が必要
  • 設定複雑性: 3つのツールの適切な統合
  • 実行時間: E2Eテストによる全体的な実行時間増加

軽減策

  • 詳細なテストガイドラインの作成
  • CI/CDでの並列実行によるテスト時間短縮
  • テストユーティリティの共通化

テスト戦略詳細

テストピラミッド

       E2E (10%)
      /         \
   統合テスト (30%)
   /             \
単体テスト (60%)

単体テスト (Vitest)

// ドメインロジックテスト例
describe('Puyo', () => {
  it('同じ色のぷよを判定できる', () => {
    const puyo1 = new Puyo(PuyoColor.RED);
    const puyo2 = new Puyo(PuyoColor.RED);

    expect(puyo1.isSameColor(puyo2)).toBe(true);
  });
});

コンポーネントテスト (React Testing Library)

describe('GameBoard', () => {
  it('ゲームフィールドを表示する', () => {
    render(<GameBoard field={mockField} />);

    expect(screen.getByRole('grid')).toBeInTheDocument();
  });
});

E2Eテスト (Playwright)

test('ゲーム開始から連鎖まで', async ({ page }) => {
  await page.goto('/');
  await page.click('button:has-text("スタート")');

  // ぷよ操作
  await page.keyboard.press('ArrowLeft');
  await page.keyboard.press('Space');

  // 連鎖確認
  await expect(page.locator('.chain-counter')).toContainText('1連鎖');
});

設定詳細

Vitest設定

// vitest.config.ts
export default {
  test: {
    environment: 'jsdom',
    setupFiles: ['./src/test/setup.ts'],
    coverage: {
      reporter: ['text', 'json', 'html'],
      threshold: {
        global: {
          statements: 85,
          branches: 85,
          functions: 85,
          lines: 85
        }
      }
    }
  }
};

Playwright設定

// playwright.config.ts
export default {
  testDir: './e2e',
  projects: [
    { name: 'chromium', use: devices['Desktop Chrome'] },
    { name: 'firefox', use: devices['Desktop Firefox'] },
    { name: 'webkit', use: devices['Desktop Safari'] }
  ],
  webServer: {
    command: 'npm run preview',
    port: 4173
  }
};

CI/CD統合

# GitHub Actions設定例
- name: Run unit tests
  run: npm run test:unit

- name: Run integration tests  
  run: npm run test:integration

- name: Install Playwright
  run: npx playwright install

- name: Run E2E tests
  run: npm run test:e2e

カバレッジ目標

テストタイプ 目標カバレッジ
単体テスト 85%以上
統合テスト 主要フロー100%
E2Eテスト 全ユーザーシナリオ

コンプライアンス

この決定の遵守は以下により確認:

  • vitest.config.ts の存在と適切な設定
  • playwright.config.ts の存在
  • CI/CDでの自動テスト実行
  • カバレッジレポートの生成

備考

  • 決定者: 開発チーム
  • 影響範囲: テスト全体
  • レビュー予定: 最初のマイルストーン完了後