# 帳票設計書 22-テスト集約レポート

## 概要

本ドキュメントは、OpenSearch プロジェクトの Gradle ビルドシステムで生成されるテスト結果の集約レポート（Aggregate Test Report）の設計仕様を定義する。全サブプロジェクトのテスト結果を単一のHTMLレポートに集約して出力する帳票である。

### 本帳票の処理概要

テスト集約レポートは、OpenSearch のマルチプロジェクト Gradle ビルドにおいて、全サブプロジェクトのユニットテスト結果を1つの HTML レポートに集約して出力する帳票である。

**業務上の目的・背景**：OpenSearch は数百のサブプロジェクトから構成されるマルチプロジェクトビルドであり、各プロジェクトが個別にテストを実行する。開発者や CI/CD パイプラインにおいて、全プロジェクトのテスト結果を横断的に確認する必要がある。本レポートは Gradle の `AggregateTestReport` 機能を活用し、分散したテスト結果を単一の閲覧ポイントに集約することで、テスト全体の合否状況を効率的に把握できるようにする。

**帳票の利用シーン**：CI/CD パイプラインでのビルド結果確認、プルリクエストのレビュー時にテスト全体の合否を確認する場面、リリース前の品質確認、テスト失敗の原因調査時にどのプロジェクトで失敗が発生したかの特定に利用される。

**主要な出力内容**：
1. テストスイート全体のサマリー（成功・失敗・スキップ件数、成功率）
2. サブプロジェクト別のテスト結果一覧
3. 各テストクラス・テストメソッドの合否結果
4. 失敗したテストの詳細情報（例外メッセージ、スタックトレース）
5. テスト実行時間の統計

**帳票の出力タイミング**：`./gradlew check` タスクの実行時、または `./gradlew testAggregateTestReport` タスクの直接実行時に生成される。`check` タスクは `testAggregateTestReport` に依存しているため、チェックフェーズの一部として自動実行される。

**帳票の利用者**：OpenSearch の開発者、CI/CD パイプライン管理者、プルリクエストレビュアー、リリースマネージャー

## 帳票種別

集計表（HTML レポート形式）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | ビルドレポート | ローカルファイルシステム | `./gradlew testAggregateTestReport` または `./gradlew check` |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | HTML |
| 用紙サイズ | N/A（ブラウザ表示） |
| 向き | N/A |
| ファイル名 | `build/reports/tests/unit-test/aggregated-results/index.html` |
| 出力方法 | ローカルファイルシステムへの出力 |
| 文字コード | UTF-8 |

### HTML固有設定

| 項目 | 内容 |
|-----|------|
| XML レポート同時出力 | 有（JUnit XML 形式、Jenkins連携用） |
| CSS/JS 同梱 | Gradle標準のHTMLレポートテンプレート使用 |

## 帳票レイアウト

### レイアウト概要

Gradle 標準の TestReport HTML テンプレートに基づく。サマリーページとプロジェクト・クラス・テストメソッドの階層的なナビゲーション構造を持つ。

```
┌─────────────────────────────────────────────────────────────┐
│                     サマリー部                                │
│  テスト総数 | 成功数 | 失敗数 | スキップ数 | 成功率 | 実行時間  │
├─────────────────────────────────────────────────────────────┤
│                  プロジェクト一覧                              │
│  プロジェクト名 | テスト数 | 失敗数 | スキップ数 | 実行時間     │
├─────────────────────────────────────────────────────────────┤
│               テストクラス一覧（プロジェクト別）                 │
│  クラス名 | テスト数 | 失敗数 | スキップ数 | 実行時間            │
├─────────────────────────────────────────────────────────────┤
│             テストメソッド詳細（クラス別）                      │
│  メソッド名 | 結果 | 実行時間 | [エラー詳細]                    │
└─────────────────────────────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | レポートタイトル | "Test Summary" | Gradle テンプレート | テキスト |
| 2 | テスト総数 | 全テストメソッドの合計数 | JUnit XML から集計 | 整数 |
| 3 | 成功数 | 成功したテスト数 | JUnit XML から集計 | 整数 |
| 4 | 失敗数 | 失敗したテスト数 | JUnit XML から集計 | 整数 |
| 5 | スキップ数 | スキップされたテスト数 | JUnit XML から集計 | 整数 |
| 6 | 成功率 | 成功数 / テスト総数 * 100 | 計算値 | パーセンテージ |
| 7 | 総実行時間 | 全テストの合計実行時間 | JUnit XML から集計 | 秒 |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | プロジェクト名 | サブプロジェクトのパス | Gradle プロジェクト構造 | 文字列 | 可変 |
| 2 | テストクラス名 | FQCNまたは簡易クラス名 | JUnit XML の testsuite 要素 | 文字列 | 可変 |
| 3 | テストメソッド名 | テストメソッド名 | JUnit XML の testcase 要素 | 文字列 | 可変 |
| 4 | 結果 | 成功/失敗/スキップ | JUnit XML のステータス | バッジ | 固定 |
| 5 | 実行時間 | テストの実行時間 | JUnit XML の time 属性 | 秒 | 可変 |
| 6 | エラー詳細 | 失敗時の例外メッセージ・スタックトレース | JUnit XML の failure/error 要素 | テキスト | 可変 |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 生成日時 | レポート生成のタイムスタンプ | Gradle 実行時刻 | 日時 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| testSuiteName | 集約対象のテストスイート名（"test" 固定） | Yes |
| サブプロジェクトフィルタ | 全サブプロジェクトが対象（フィルタなし） | N/A |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | プロジェクト名 | 昇順 |
| 2 | テストクラス名 | 昇順 |
| 3 | テストメソッド名 | 昇順 |

### 改ページ条件

改ページは発生しない（HTML の単一ページ内でスクロール表示）。

## データベース参照仕様

### 参照テーブル一覧

本帳票はデータベースを使用せず、各サブプロジェクトの JUnit XML テスト結果ファイルを入力とする。

| データソース | 用途 | 取得方法 |
|-----------|------|---------|
| JUnit XML テスト結果 | 各サブプロジェクトのテスト結果 | `{project}/build/test-results/test/*.xml` |
| Gradle プロジェクト構造 | サブプロジェクト一覧 | Gradle の project 構造から自動収集 |

### データソース別参照項目詳細

#### JUnit XML テスト結果

| 参照項目 | 帳票項目との対応 | 取得条件 | 備考 |
|---------|----------------|---------|------|
| testsuite@name | テストクラス名 | 全 XML ファイルを走査 | FQCN形式 |
| testsuite@tests | テスト数 | 同上 | 整数値 |
| testsuite@failures | 失敗数 | 同上 | 整数値 |
| testsuite@errors | エラー数 | 同上 | 整数値 |
| testsuite@skipped | スキップ数 | 同上 | 整数値 |
| testsuite@time | 実行時間 | 同上 | 秒数（浮動小数点） |
| testcase@name | テストメソッド名 | 同上 | 文字列 |
| testcase/failure | 失敗詳細 | 失敗テストのみ | スタックトレース含む |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| テスト総数 | SUM(全サブプロジェクトの tests) | N/A | 整数 |
| 成功数 | テスト総数 - 失敗数 - エラー数 - スキップ数 | N/A | 整数 |
| 失敗数 | SUM(全サブプロジェクトの failures + errors) | N/A | 整数 |
| 成功率 | (成功数 / テスト総数) * 100 | 小数第1位 | パーセンテージ |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[gradlew check / testAggregateTestReport] --> B[Gradle タスク依存解決]
    B --> C[各サブプロジェクトの test タスク実行]
    C --> D[JUnit XML テスト結果生成]
    D --> E[AggregateTestReport タスク実行]
    E --> F[全サブプロジェクトのテスト結果収集]
    F --> G[テスト結果の集約・統計計算]
    G --> H[HTML レポート生成]
    H --> I[build/reports/tests/ に出力]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| テスト失敗 | いずれかのテストが失敗 | レポート内に失敗テストの詳細を表示 | 失敗テストを修正して再実行 |
| テスト結果なし | テストが1件も実行されなかった | 空のレポートが生成される | テスト対象の存在を確認 |
| ビルドエラー | コンパイルエラー等でテスト未実行 | Gradle ビルドエラー | コンパイルエラーを修正 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数千～数万テストケース（全サブプロジェクト合計） |
| 目標出力時間 | テスト実行後のレポート生成は数秒～数十秒 |
| 同時出力数上限 | 1（ビルドプロセスあたり1レポート） |

## セキュリティ考慮事項

- テスト結果には本番データは含まれないが、テストクラス名やメソッド名から内部実装の構造が推測可能
- CI/CD パイプラインの成果物として保存する場合は、適切なアクセス制御を設定すること
- テスト出力にシークレット情報が含まれないよう、テストコード側で配慮が必要

## 備考

- `testAggregateTestReport` タスクは Gradle の `AggregateTestReport` 型で定義されている（build.gradle 行720）
- `testSuiteName` は `"test"` に設定されており、ユニットテストのみが集約対象となる
- `check` タスクに `testAggregateTestReport` が依存として登録されている（build.gradle 行731-733）
- JUnit XML レポートは Jenkins 連携用に有効化されている（build.gradle 行727-729）

---

## コードリーディングガイド

本帳票を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

テスト集約レポートの入力となるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | build.gradle | `build.gradle` | ルートプロジェクトのビルド定義。行718-724 で `testAggregateTestReport` タスクの定義、行726-729 で JUnit XML の有効化 |

**読解のコツ**: Gradle の `AggregateTestReport` は Gradle 7.4 以降で導入された機能で、`reporting` ブロック内で定義される。`testSuiteName` でどのテストスイートを集約対象にするかを指定する。

#### Step 2: エントリーポイントを理解する

タスク実行の起点と依存関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | build.gradle | `build.gradle` | 行731-733: `check` タスクが `testAggregateTestReport` に依存。これにより `./gradlew check` 実行時に自動的に集約レポートが生成される |

**主要処理フロー**:
1. **行720**: `AggregateTestReport` 型のタスクとして `testAggregateTestReport` を定義
2. **行721**: `testSuiteName = "test"` で集約対象を "test" スイートに限定
3. **行727-729**: `TestTaskReports` タイプの全タスクで `junitXml.enabled = true` を設定
4. **行731-733**: `check` タスクに `testAggregateTestReport` を依存として追加

#### Step 3: テスト実行基盤を理解する

各サブプロジェクトのテスト実行設定を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | OpenSearchTestBasePlugin.java | `buildSrc/src/main/java/org/opensearch/gradle/OpenSearchTestBasePlugin.java` | 全テストタスクに共通設定を適用するプラグイン。行78-233 でテスト実行の詳細設定（ヒープサイズ、JVM引数、システムプロパティ等） |

**主要処理フロー**:
- **行69**: デフォルトの test タスクは `**/*Tests.class` のみを対象
- **行78-84**: 各テストタスクに ErrorReportingTestListener を登録
- **行115**: テストの最大並列フォーク数を設定

### プログラム呼び出し階層図

```
./gradlew check
    |
    +-- testAggregateTestReport (AggregateTestReport)     [build.gradle 行732]
        |
        +-- 各サブプロジェクトの test タスク (Test)
            |
            +-- OpenSearchTestBasePlugin 設定適用           [OpenSearchTestBasePlugin.java]
            |   +-- ErrorReportingTestListener 登録         [行81-84]
            |   +-- JVM引数・システムプロパティ設定            [行119-193]
            |
            +-- JUnit XML 出力 (TestTaskReports)           [build.gradle 行727-729]
            |
            +-- テスト結果を JUnit XML に書き出し
        |
        +-- 全サブプロジェクトの JUnit XML を集約
        |
        +-- HTML レポート生成
```

### データフロー図

```
[入力]                          [処理]                              [出力]

各サブプロジェクトの        --> AggregateTestReport タスク      --> HTML レポート
テスト実行結果                  |                                  (index.html)
(JUnit XML)                    |
                                v
                           テスト結果集約・統計計算            --> JUnit XML
                                                               (Jenkins連携用)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| build.gradle | `build.gradle` | 設定 | ルートプロジェクトのビルド定義、testAggregateTestReport タスク定義 |
| OpenSearchTestBasePlugin.java | `buildSrc/src/main/java/org/opensearch/gradle/OpenSearchTestBasePlugin.java` | ソース | テストタスクの共通設定プラグイン |
| ErrorReportingTestListener.java | `buildSrc/src/main/java/org/opensearch/gradle/test/ErrorReportingTestListener.java` | ソース | テスト出力とエラー報告のリスナー |
| server/build.gradle | `server/build.gradle` | 設定 | サーバーモジュールのビルド定義（サブプロジェクト例） |
