Skip to content

テスト戦略

概要

ぷよぷよゲームの品質を保証するため、テスト駆動開発(TDD)を採用し、包括的なテスト戦略を策定します。

TDD開発サイクル

uml diagram

3層テスト戦略

uml diagram

1. 単体テスト(Unit Tests)

対象:

  • ドメインモデル(Puyo, Field, Game, Chain)
  • ビジネスロジック(スコア計算、連鎖検出)
  • ユーティリティ関数
  • 個別のReactコンポーネント

ツール:

  • Vitest: 高速なテストランナー
  • React Testing Library: コンポーネントテスト
  • Mock Service Worker: API モック

テストケース例:

describe('Puyo', () => {
  test('同じ色のぷよを判定できる', () => {
    const puyo1 = new Puyo(PuyoColor.RED);
    const puyo2 = new Puyo(PuyoColor.RED);
    const puyo3 = new Puyo(PuyoColor.BLUE);

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

describe('Field', () => {
  test('4つ以上連結したぷよを検出できる', () => {
    const field = new Field(6, 13);
    // ぷよを配置
    field.placePuyo(new Puyo(PuyoColor.RED), 0, 12);
    field.placePuyo(new Puyo(PuyoColor.RED), 1, 12);
    field.placePuyo(new Puyo(PuyoColor.RED), 2, 12);
    field.placePuyo(new Puyo(PuyoColor.RED), 3, 12);

    const connected = field.findConnectedPuyos(0, 12);
    expect(connected).toHaveLength(4);
  });
});

2. 統合テスト(Integration Tests)

対象:

  • レイヤー間の連携
  • 状態管理の統合
  • イベントフローの検証

ツール:

  • Vitest
  • React Testing Library
  • Testing Hooks

テストケース例:

describe('GameController Integration', () => {
  test('ぷよの移動から表示更新まで', async () => {
    const { getByTestId } = render(<App />);
    const gameBoard = getByTestId('game-board');

    // 左移動
    fireEvent.keyDown(document, { key: 'ArrowLeft' });

    // フィールドの更新を確認
    await waitFor(() => {
      expect(gameBoard).toHaveTextContent('移動完了');
    });
  });
});

3. E2Eテスト(End-to-End Tests)

対象:

  • 完全なユーザーシナリオ
  • ブラウザ互換性
  • パフォーマンス

ツール:

  • Playwright: クロスブラウザ自動化
  • Lighthouse: パフォーマンス測定

テストケース例:

test('ゲーム開始から連鎖まで', async ({ page }) => {
  await page.goto('/');

  // ゲーム開始
  await page.click('button:has-text("スタート")');

  // ぷよ操作
  await page.keyboard.press('ArrowLeft');
  await page.keyboard.press('ArrowLeft');
  await page.keyboard.press('Space'); // ハードドロップ

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

レイヤー別テスト戦略

プレゼンテーション層

テスト内容:

  • コンポーネントの表示
  • ユーザーインタラクション
  • レスポンシブデザイン

アプローチ:

  • スナップショットテスト
  • ビジュアルリグレッションテスト
  • アクセシビリティテスト

アプリケーション層

テスト内容:

  • ユースケースの実行
  • 入力検証
  • エラーハンドリング

アプローチ:

  • モックを使用した独立テスト
  • 境界値テスト
  • 異常系テスト

ドメイン層

テスト内容:

  • ビジネスルール
  • 不変条件
  • ドメインイベント

アプローチ:

  • プロパティベーステスト
  • 状態遷移テスト
  • イベント駆動テスト

インフラストラクチャ層

テスト内容:

  • 外部システム連携
  • データ永続化
  • パフォーマンス

アプローチ:

  • インメモリ実装でのテスト
  • 契約テスト
  • 負荷テスト

パフォーマンステスト

uml diagram

パフォーマンス目標:

  • 60 FPS の維持
  • 入力遅延 < 16ms
  • メモリリーク 0
  • 初回描画 < 3秒

テストデータ管理

フィクスチャ

// テスト用フィールドデータ
export const fixtures = {
  emptyField: createEmptyField(),
  nearChain: createFieldWithPattern([
    '......',
    '......',
    '...R..',
    '..RR..',
    '..RB..',
  ]),
  gameOver: createFieldWithPattern([
    '..RB..',
    'RRBBGG',
    'RRBBGG',
    // ... 満杯状態
  ])
};

ファクトリー

// テストデータ生成
export const factories = {
  puyo: (color?: PuyoColor) => new Puyo(color || PuyoColor.RED),
  field: (width = 6, height = 13) => new Field(width, height),
  game: (status?: GameStatus) => new Game(status || GameStatus.PLAYING)
};

CI/CDでのテスト実行

# .github/workflows/test.yml
name: Test

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3

      - name: Install dependencies
        run: npm ci

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

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

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

      - name: Upload coverage
        uses: codecov/codecov-action@v3

テストカバレッジ目標

レイヤー別カバレッジ目標

レイヤー カバレッジ目標
ドメイン層 95%以上
アプリケーション層 85%以上
プレゼンテーション層 80%以上
インフラストラクチャ層 70%以上
全体 85%以上

Codecov統合設定

項目 目標値 闾値
全体プロジェクト 85% 2%
新規コード(Patch) 90% 5%
関数カバレッジ 90% -
ブランチカバレッジ 80% -

カバレッジ管理機能

  • PRコメント: カバレッジ変化の自動レポート
  • トレンド解析: 長期的な品質変化の追跡
  • 闾値アラート: カバレッジ低下時のCI失敗
  • バッジ表示: READMEでのリアルタイムステータス

テスト実行方針

開発時

  • ファイル保存時に関連テストを自動実行
  • プリコミットフックでテスト実行
  • TDDサイクルの厳守

CI/CD

  • プルリクエスト時に全テスト実行
  • マージ時にE2Eテスト実行
  • 定期的な負荷テスト実行

リリース前

  • 全ブラウザでのE2Eテスト
  • パフォーマンステスト
  • セキュリティテスト