# テスト方針書

## 概要

本ドキュメントは、GitLabプロジェクトにおけるテスト方針を定義するものです。GitLabは大規模なRuby on Railsアプリケーションであり、バックエンド（Ruby/Rails）とフロントエンド（JavaScript/Vue.js）の両方に対して包括的なテスト戦略を採用しています。テストはRSpec（バックエンド）とJest（フロントエンド）を中心に構成され、E2Eテストや各種自動化テストを含む多層的なテスト体制を構築しています。

## テスト戦略

### テストレベル

| レベル | 目的 | 担当 |
| --- | --- | --- |
| 単体テスト (Unit) | 個々のクラス、モジュール、メソッドの機能を検証する。モデル、サービス、ヘルパー、ワーカー等の個別コンポーネントをテスト | 開発者 |
| 結合テスト (Integration) | 複数のコンポーネント間の連携を検証する。API、コントローラー、データベース操作の統合動作をテスト | 開発者 |
| システムテスト (System) | ブラウザを介したエンドツーエンドのユーザーシナリオを検証する。Capybara + Seleniumを使用したUIテスト | 開発者・QAエンジニア |
| 受入テスト (E2E/QA) | 本番環境に近い構成でのエンドツーエンドテスト。Omnibus GitLabやGDK上での統合テスト | QAエンジニア |

### テスト種別

| 種別 | 概要 | 実施タイミング |
| --- | --- | --- |
| 機能テスト | アプリケーションの機能要件が正しく実装されていることを検証。RSpec、Jest、Capybaraによるテスト | CI/CDパイプライン実行時（毎コミット） |
| マイグレーションテスト | データベースマイグレーションの正確性を検証。up/downの両方向をテスト | マイグレーション変更時 |
| 性能テスト | アプリケーションのパフォーマンス特性を検証。ベンチマークステージで実行 | スケジュールパイプライン、リリース前 |
| セキュリティテスト | DASTを含むセキュリティスキャン | CI/CDパイプライン、リリース前 |
| 静的解析 | RuboCop、ESLint等によるコード品質チェック | CI/CDパイプライン実行時（毎コミット） |

## テスト環境

| 環境 | 用途 | 構成 |
| --- | --- | --- |
| CI/CD環境 | 自動テスト実行 | GitLab CI、Docker、PostgreSQL 16、Redis、Elasticsearch |
| ローカル開発環境 | 開発者によるテスト実行 | GDK (GitLab Development Kit)、ローカルPostgreSQL |
| QA環境 | E2Eテスト実行 | Omnibus GitLab、Docker構成、専用テストランナー |
| レビュー環境 | マージリクエストごとのテスト | 動的に作成されるレビュー環境 |

## テストツール

### バックエンド（Ruby/Rails）

| ツール | 用途 | バージョン |
| --- | --- | --- |
| RSpec | テストフレームワーク | rspec-rails |
| RSpec-retry | フレーキーテスト対策のリトライ機能 | rspec-retry |
| Shoulda Matchers | Railsモデルテスト用マッチャー | shoulda-matchers |
| FactoryBot | テストデータ生成 | factory_bot_rails |
| TestProf | テストパフォーマンス最適化 (let_it_be, factory_default) | test_prof |
| Capybara | ブラウザテスト（フィーチャースペック） | capybara |
| Selenium WebDriver | ブラウザ自動化 | selenium-webdriver |
| SimpleCov | コードカバレッジ計測 | simplecov |
| Crystalball | 予測テストマッピング | crystalball |
| Knapsack | テスト並列化・分散 | knapsack |
| WebMock | HTTPリクエストスタブ | webmock |
| VCR | HTTPインタラクション記録・再生 | vcr |

### フロントエンド（JavaScript/Vue.js）

| ツール | 用途 | バージョン |
| --- | --- | --- |
| Jest | テストフレームワーク | jest |
| Jest-junit | JUnitレポート出力 | jest-junit |
| @vue/test-utils | Vue.jsコンポーネントテスト | @vue/test-utils (Vue 2/3) |
| @vue/vue2-jest / @vue/vue3-jest | Vueファイル変換 | 環境変数VUE_VERSIONにより切替 |
| babel-jest | ES6+コード変換 | babel-jest |
| jest-canvas-mock | Canvasモック | jest-canvas-mock |
| Axe-rspec | アクセシビリティテスト | axe-rspec |

### CI/CDツール

| ツール | 用途 | バージョン |
| --- | --- | --- |
| GitLab CI | CI/CDパイプライン | GitLab組み込み |
| Docker | コンテナ化テスト環境 | CI環境標準 |
| PostgreSQL | テストデータベース | 16 |
| Redis | キャッシュ・キュー | CI環境標準 |
| Elasticsearch | 検索機能テスト | CI環境標準 |
| Chrome (Headless) | ブラウザテスト | CI環境標準 |

## カバレッジ目標

| 対象 | 目標値 |
| --- | --- |
| 行カバレッジ (Line Coverage) | SimpleCovによる計測（具体的目標値はプロジェクトで設定） |
| 分岐カバレッジ (Branch Coverage) | SimpleCovで有効化 (`enable_coverage :branch`) |
| フロントエンドカバレッジ | Jest coverageReportersによる計測（json, lcov, text-summary, clover） |

### カバレッジ計測対象

**バックエンド（SimpleCov）:**
- app/channels, app/components, app/controllers
- app/enums, app/events, app/experiments
- app/finders, app/graphql, app/helpers
- app/mailers, app/models, app/policies
- app/presenters, app/replicators, app/serializers
- app/services, app/uploaders, app/validators
- app/views, app/workers
- lib/, config/, db/migrate, db/post_migrate
- ee/（Enterprise Edition）各対応ディレクトリ

**フロントエンド（Jest）:**
- app/assets/javascripts/**/*.{js,vue}
- ee/app/assets/javascripts/**/*.{js,vue}（EE環境）

## テストデータ

### テストデータ準備方針

1. **FactoryBot**: テストデータの生成にはFactoryBotを使用
   - `spec/factories/` ディレクトリにファクトリ定義を配置
   - `let_it_be` や `create_default` による効率的なデータ生成

2. **フィクスチャ**: 静的なテストデータ
   - `spec/fixtures/` ディレクトリに配置
   - フロントエンドフィクスチャは `tmp/tests/frontend/fixtures` に生成

3. **テストリポジトリ**: Gitリポジトリテスト用
   - `gitlab-test`, `gitlab-test-fork` などのテストリポジトリを使用
   - `setup-test-env` ジョブで準備

4. **データベース**: トランザクションテスト
   - `use_transactional_fixtures = true` による自動ロールバック
   - マイグレーションテストでは削除戦略を使用

## 不具合管理

### フレーキーテスト管理

1. **検出と報告**:
   - `gitlab-rspec_flaky` gemによるフレーキーテスト検出
   - `FLAKY_RSPEC_SUITE_REPORT_PATH` にレポート出力
   - CIパイプラインでのフレーキーテスト追跡

2. **隔離（Quarantine）**:
   - `:quarantine` メタデータでフレーキーテストをマーク
   - `FAST_QUARANTINE` による迅速な隔離処理
   - 隔離テストはCI環境では通常スキップ

3. **リトライ戦略**:
   - `rspec-retry` による自動リトライ
   - CI環境では最大2回実行（初回 + 1リトライ）
   - 新規プロセスでの失敗テスト再実行 (`RETRY_FAILED_TESTS_IN_NEW_PROCESS`)

### テスト失敗時の対応

1. **Issue自動作成**:
   - `CREATE_RAILS_TEST_FAILURE_ISSUES`: テスト失敗時のIssue自動作成
   - `CREATE_RAILS_FLAKY_TEST_ISSUES`: フレーキーテスト検出時のIssue作成
   - `CREATE_RAILS_SLOW_TEST_ISSUES`: 遅いテスト検出時のIssue作成

2. **ClickHouse連携**:
   - `GLCI_EXPORT_TEST_METRICS`: テスト結果のClickHouseへのエクスポート
   - テスト実行メトリクスの分析・可視化

## CI/CD連携

### パイプラインステージ

GitLabのCI/CDパイプラインは以下のステージで構成されています：

1. **sync** - 同期処理
2. **preflight** - 事前チェック
3. **prepare** - テスト環境準備 (`setup-test-env`, `compile-test-assets`)
4. **build-images** - Dockerイメージビルド
5. **fixtures** - テストフィクスチャ生成 (`frontend_fixture`)
6. **lint** - 静的解析 (`rubocop`, `eslint`)
7. **test-frontend** - フロントエンドテスト (`jest`)
8. **test** - バックエンドテスト (`rspec`)
9. **post-test** - テスト後処理
10. **review** - レビュー環境
11. **qa** - E2Eテスト (`e2e:test-on-omnibus-ee`)
12. **post-qa** - QA後処理
13. **benchmark** - ベンチマーク

### 主要なテストジョブ

**RSpec (バックエンド):**
- `rspec migration pg16` - マイグレーションテスト
- `rspec background_migration pg16` - バックグラウンドマイグレーションテスト
- `rspec unit pg16` - 単体テスト
- `rspec integration pg16` - 結合テスト
- `rspec system pg16` - システムテスト（ブラウザテスト）

**Jest (フロントエンド):**
- フロントエンドテストはJestで実行
- Vue 2/Vue 3両方のテスト対応（`VUE_VERSION` 環境変数）

**E2E (QA):**
- `e2e:test-on-omnibus-ee` - Omnibus EEでのE2Eテスト
- `e2e:test-on-omnibus-ce` - Omnibus CEでのE2Eテスト
- `e2e:test-on-gdk` - GDK上でのE2Eテスト

### 予測テスト（Predictive Testing）

変更されたファイルに基づいて実行するテストを予測し、テスト実行時間を短縮：

- **Crystalball**: テストとソースコードのマッピング
- **マッピングファイル**: `crystalball/mapping.json`, `crystalball/packed-mapping.json`
- **予測テストパイプライン**: `.gitlab/ci/rails/rspec-predictive.gitlab-ci.yml.erb`

### テスト並列化

- **Knapsack**: テスト実行時間に基づくテスト分散
- **並列ジョブ**: `parallel` キーワードによる複数ジョブ実行
- **RSpec parallel**: 複数プロセスでのテスト実行

## 備考

### テスト実行のベストプラクティス

1. **ローカルでのテスト実行**:
   ```bash
   # RSpecテスト
   bin/rspec spec/models/user_spec.rb

   # Jestテスト
   yarn jest spec/frontend/vue_shared/components/
   ```

2. **フィーチャーフラグのスタブ**:
   - テストではすべてのフィーチャーフラグがデフォルトで有効
   - `stub_feature_flags` で個別にスタブ可能

3. **タイムゾーン**:
   - テスト環境では `TZ=GMT` に統一

4. **テストタイムアウト**:
   - CI環境: 10秒（Jest）
   - ローカル環境: 5秒（Jest）
   - ジョブタイムアウト: 90分

### 追加リソース

- [GitLab Testing Guide](https://docs.gitlab.com/ee/development/testing_guide/)
- [RSpec Best Practices](https://docs.gitlab.com/ee/development/testing_guide/best_practices.html)
- [Frontend Testing Guide](https://docs.gitlab.com/ee/development/testing_guide/frontend_testing.html)
