LESSON 30分

テスト自動化とCI統合

ストーリー

「テストを書いても、手動で実行していたら意味がない。 CIに組み込んで、PRごとに自動でテストが走る仕組みを作ろう」

松本先輩がGitHub Actions のワークフローを開いた。

「品質ゲート。これを通らないとマージできない。 テスト、リント、カバレッジチェック......全てを自動化する。 これが『品質の番人』を自動化するということだ」


テスト自動化の全体像

PR が作成される
     │
     ▼
┌────────────────────────┐
│  品質ゲート(自動実行)  │
├────────────────────────┤
│  1. リント・フォーマット │
│  2. 型チェック          │
│  3. ユニットテスト      │
│  4. インテグレーション   │
│  5. E2Eテスト           │
│  6. カバレッジチェック   │
│  7. セキュリティスキャン │
└────────┬───────────────┘
         │
    全て通過?
    ├── Yes → マージ可能
    └── No  → マージ不可(修正が必要)

GitHub Actions でのテスト自動化

完全なワークフロー例

yaml
# .github/workflows/quality-gate.yml
name: Quality Gate

on:
  pull_request:
    branches: [main, develop]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  # ステップ1: リント・型チェック
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npm run lint
      - run: npm run type-check
      - run: npm run format:check

  # ステップ2: ユニットテスト + カバレッジ
  unit-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npm run test:unit -- --coverage
      - name: Check coverage threshold
        run: |
          npx jest --coverage --coverageThreshold='{"global":{"branches":80,"functions":80,"lines":80,"statements":80}}'

  # ステップ3: インテグレーションテスト
  integration-test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_DB: test_db
          POSTGRES_USER: test_user
          POSTGRES_PASSWORD: test_pass
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npx prisma migrate deploy
        env:
          DATABASE_URL: postgresql://test_user:test_pass@localhost:5432/test_db
      - run: npm run test:integration
        env:
          TEST_DATABASE_URL: postgresql://test_user:test_pass@localhost:5432/test_db

  # ステップ4: E2Eテスト
  e2e-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - name: Install Playwright browsers
        run: npx playwright install --with-deps
      - name: Run E2E tests
        run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 7

カバレッジレポートの活用

PR へのカバレッジレポート投稿

yaml
  unit-test:
    runs-on: ubuntu-latest
    steps:
      # ... 省略
      - run: npm run test:unit -- --coverage --coverageReporters=json-summary
      - name: Coverage Report
        uses: davelosert/vitest-coverage-report-action@v2
        if: always()
        with:
          json-summary-path: ./coverage/coverage-summary.json

カバレッジの閾値設定

javascript
// jest.config.js
module.exports = {
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80,
    },
    // 重要なディレクトリはより高い閾値
    './src/domain/': {
      branches: 90,
      functions: 90,
      lines: 90,
      statements: 90,
    },
  },
};

ブランチ保護ルール

テストが通らないとマージできないようにGitHubで設定します。

GitHub Settings → Branches → Branch protection rules

main ブランチの保護ルール:
├── ✅ Require status checks to pass before merging
│   ├── lint
│   ├── unit-test
│   ├── integration-test
│   └── e2e-test
├── ✅ Require pull request reviews before merging
│   └── Required approving reviews: 1
├── ✅ Require branches to be up to date before merging
└── ✅ Do not allow bypassing the above settings

テスト実行の最適化

並列実行

yaml
  unit-test:
    strategy:
      matrix:
        shard: [1, 2, 3]
    steps:
      - run: npm run test:unit -- --shard=${{ matrix.shard }}/3

変更されたファイルのみテスト

yaml
  smart-test:
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - run: npm ci
      - name: Run affected tests
        run: npx jest --changedSince=origin/main
最適化手法効果適用場面
並列実行(シャーディング)テスト時間短縮テスト数が多い場合
変更ファイルのみ不要なテスト実行を削減モノレポ、大規模プロジェクト
キャッシュ活用npm install の高速化全てのCI実行
concurrency 制御重複実行の防止頻繁なpush時

まとめ

項目ポイント
品質ゲートリント、テスト、カバレッジを自動チェック
CI統合GitHub Actions でPRごとに自動実行
ブランチ保護テスト通過をマージの必須条件にする
最適化並列実行、変更ファイル限定、キャッシュ

チェックリスト

  • GitHub Actions でテスト自動化ワークフローを書ける
  • カバレッジの閾値設定ができる
  • ブランチ保護ルールの設定を理解した
  • テスト実行の最適化手法を3つ以上説明できる

次のステップへ

テスト自動化とCI統合を学んだら、次は演習でテストスイートを実際に構築しましょう。


推定読了時間: 30分