# 帳票設計書 2-VerboseReporter

## 概要

本ドキュメントは、Jestテストフレームワークにおける詳細モードテスト結果レポーター「VerboseReporter」の設計仕様を定義する。VerboseReporterは、DefaultReporterを継承し、各テストケースの実行結果を階層構造で詳細に表示するレポーターである。

### 本帳票の処理概要

VerboseReporterは、Jestの`--verbose`オプションが指定された場合に使用されるレポーターであり、テストスイート内の各テストケース（describe/it ブロック）を階層的に表示し、個々のテストの成功・失敗・スキップ・TODO状態を視覚的に示す。DefaultReporterの機能に加えて、テストケースごとの詳細な結果をネスト構造で出力する。

**業務上の目的・背景**：大規模なテストスイートにおいて、どのテストケースが成功・失敗したかを一目で把握することは重要である。VerboseReporterは、テストケースをdescribeブロックの階層に従って表示することで、テストの構造を可視化し、問題のあるテストを素早く特定できるようにする。特にデバッグ時や、テストカバレッジの確認時に有用である。

**帳票の利用シーン**：`jest --verbose`コマンドで実行した場合、または`jest.config.js`で`verbose: true`を設定した場合に使用される。CI/CDログでの詳細な結果確認、テスト構造の可視化、デバッグ時の個別テスト状態確認などに利用される。

**主要な出力内容**：
1. テストファイルごとのPASS/FAIL状態（DefaultReporterと同様）
2. describeブロックの階層構造
3. 各テストケースの成功/失敗/スキップ/TODO状態とアイコン表示
4. 各テストケースの実行時間
5. エラーメッセージとスタックトレース（失敗時）

**帳票の出力タイミング**：各テストファイルの実行完了時に、そのファイル内のすべてのテストケースの結果が階層構造で出力される。

**帳票の利用者**：ソフトウェア開発者、QAエンジニア、テスト設計者

## 帳票種別

テスト結果レポート / 詳細コンソール出力

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| CLI-01 | コマンドライン | N/A | `jest --verbose`コマンド実行 |
| CLI-02 | 設定ファイル | N/A | `verbose: true`設定でテスト実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（コンソール出力） |
| 用紙サイズ | N/A（ターミナル幅に依存） |
| 向き | N/A |
| ファイル名 | N/A（標準出力/標準エラー出力） |
| 出力方法 | コンソール出力（stdout/stderr） |
| 文字コード | UTF-8 |

### コンソール出力設定

| 項目 | 内容 |
|-----|------|
| 色出力 | chalk ライブラリによるANSIカラー対応 |
| バッファリング | なし（デバッグ用途のため即時出力） |
| インデント | 2スペースずつのネスト |

## 帳票レイアウト

### レイアウト概要

VerboseReporterの出力は、テストファイルのヘッダーに続いて、テストケースが階層構造で表示される。

```
┌─────────────────────────────────────┐
│      テスト結果ヘッダー               │
│      (PASS/FAIL + ファイルパス)       │
├─────────────────────────────────────┤
│      describe ブロック名              │
│        ├─ テストケース1 結果          │
│        ├─ テストケース2 結果          │
│        └─ ネストされた describe       │
│             └─ テストケース3 結果     │
├─────────────────────────────────────┤
│      エラーメッセージ（失敗時）        │
├─────────────────────────────────────┤
│      スナップショット状態             │
└─────────────────────────────────────┘
```

### テスト結果ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 結果ラベル | PASS/FAIL状態 | TestResult.numFailingTests | 緑(PASS)/赤(FAIL)の反転テキスト |
| 2 | プロジェクト名 | displayName設定時のプロジェクト名 | Config.ProjectConfig.displayName | 色付きラベル |
| 3 | テストファイルパス | テストファイルの相対パス | TestResult.testFilePath | 相対パス |

### テストケース階層部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | describe名 | テストスイートのタイトル | AssertionResult.ancestorTitles | インデント付きテキスト |
| 2 | 状態アイコン | テスト結果を示すアイコン | AssertionResult.status | Unicode文字 |
| 3 | テスト名 | テストケースのタイトル | AssertionResult.title | 薄い色のテキスト |
| 4 | 実行時間 | テストケースの実行時間 | AssertionResult.duration | ミリ秒/秒表示 |

### 状態アイコン一覧

| 状態 | アイコン | 色 |
|------|---------|-----|
| passed | ✓ (success) | 緑 |
| failed | ✕ (failed) | 赤 |
| pending/skipped | ○ (pending) | 黄 |
| todo | ✎ (todo) | マゼンタ |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| verbose設定 | --verboseオプションまたはverbose: true | Yes |
| テスト実行 | Jestコマンドによるテスト実行 | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | ancestorTitles順 | 定義順 |
| 2 | テスト定義順 | 定義順 |

### 改ページ条件

N/A（コンソール出力のためスクロール表示）

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

### 参照テーブル一覧

N/A（ファイルシステムベースのテスト結果を使用）

### データ構造参照

#### AssertionResult

| 参照項目 | 帳票項目との対応 | 用途 |
|---------|----------------|------|
| ancestorTitles | describe階層 | 階層構造の構築 |
| title | テスト名 | テストケース名の表示 |
| status | 状態アイコン | 成功/失敗/スキップ判定 |
| duration | 実行時間 | 時間表示 |

#### Suite（VerboseReporter内部構造）

| 参照項目 | 帳票項目との対応 | 用途 |
|---------|----------------|------|
| title | describe名 | スイート名の表示 |
| suites | ネストされたスイート | 再帰的な階層表示 |
| tests | テストケース | テストケースの表示 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 実行時間表示 | formatTime(Math.round(duration)) | 四捨五入 | ミリ秒から秒への変換はformatTime関数で処理 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[テスト完了] --> B[onTestResult呼び出し]
    B --> C[printTestFileHeader]
    C --> D{testExecError?}
    D -->|No| E[_logTestResults]
    D -->|Yes| F[printTestFileFailureMessage]
    E --> G[groupTestsBySuites]
    G --> H[_logSuite 再帰呼び出し]
    H --> I[_logTests]
    I --> J[printTestFileFailureMessage]
    J --> K[forceFlushBufferedOutput]
    F --> K
```

### グループ化処理フロー

```mermaid
flowchart TD
    A[testResults配列] --> B[filterTestResults]
    B --> C[各テストをancestorTitlesでグループ化]
    C --> D[Suiteツリー構造を構築]
    D --> E[_logSuiteで再帰的に出力]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| テスト失敗 | status === 'failed' | 赤いアイコンとエラーメッセージ | 失敗テストを強調表示 |
| 実行エラー | testExecError が存在 | 実行時エラーメッセージ | テスト結果の代わりにエラーを表示 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数千テストケースまで対応 |
| 目標出力時間 | リアルタイム（バッファリングなし） |
| 同時出力数上限 | 1（シングルスレッド出力） |

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

- 詳細モードではテストケース名が全て表示されるため、機密情報を含むテスト名に注意
- スタックトレースには完全なファイルパスが含まれる
- CI/CDログの公開範囲を適切に設定すること

## 備考

- DefaultReporterを継承しているため、基本的な出力機能は共通
- `--expand`オプションと組み合わせることで、pendingテストも個別に表示可能
- VerboseReporterはバッファリングを無効化しており、出力が即座に表示される（デバッグ用途）

---

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

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

### 推奨読解順序

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

まず、VerboseReporterで使用されるデータ構造、特にSuite型を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | VerboseReporter.ts | `packages/jest-reporters/src/VerboseReporter.ts` | Suite型の定義（@jest/test-resultからインポート）を確認 |
| 1-2 | @jest/test-result | `node_modules/@jest/test-result` | AssertionResult型のancestorTitles, title, status, durationを確認 |

**読解のコツ**: VerboseReporterはDefaultReporterを継承しているため、まずDefaultReporterの動作を理解してから読むと良い。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | VerboseReporter.ts | `packages/jest-reporters/src/VerboseReporter.ts` | クラス定義とコンストラクタ（23-31行目） |

**主要処理フロー**:
1. **23行目**: `class VerboseReporter extends DefaultReporter` - DefaultReporterの継承
2. **28-31行目**: コンストラクタでglobalConfigを設定

#### Step 3: 出力バッファリングの無効化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | VerboseReporter.ts | `packages/jest-reporters/src/VerboseReporter.ts` | __wrapStdioのオーバーライド（35-46行目） |

**主要処理フロー**:
- **35-46行目**: `__wrapStdio` - バッファリングを無効化し、即時出力を実現
- **40-44行目**: writeを直接呼び出し、ステータスのクリア・再描画のみ実行

#### Step 4: テスト結果の出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | VerboseReporter.ts | `packages/jest-reporters/src/VerboseReporter.ts` | onTestResultオーバーライド（75-97行目） |

**主要処理フロー**:
- **75-97行目**: `onTestResult` - 親クラスのtestFinishedを呼び、詳細結果を出力
- **87-89行目**: `_logTestResults` - 階層構造での結果出力を開始

#### Step 5: グループ化処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | VerboseReporter.ts | `packages/jest-reporters/src/VerboseReporter.ts` | groupTestsBySuites（54-73行目） |

**主要処理フロー**:
- **48-52行目**: `filterTestResults` - pendingステータスのテストをフィルタリング
- **54-73行目**: `groupTestsBySuites` - ancestorTitlesに基づいてテストをネスト構造にグループ化
- **60-68行目**: 各テストのancestorTitlesを辿り、適切なスイートに配置

#### Step 6: 再帰的な出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | VerboseReporter.ts | `packages/jest-reporters/src/VerboseReporter.ts` | _logSuite, _logTests, _logTest（104-182行目） |

**主要処理フロー**:
- **104-114行目**: `_logSuite` - スイートを再帰的にログ出力
- **116-126行目**: `_getIcon` - 状態に応じたアイコンを取得
- **128-134行目**: `_logTest` - 個別テストの結果を出力
- **136-167行目**: `_logTests` - expandオプションに応じたテスト出力

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

```
VerboseReporter
    │
    ├─ DefaultReporter (継承)
    │      ├─ BaseReporter (継承)
    │      ├─ printTestFileHeader
    │      └─ printTestFileFailureMessage
    │
    ├─ filterTestResults (static)
    │
    ├─ groupTestsBySuites (static)
    │
    ├─ _logTestResults
    │      └─ _logSuite (再帰)
    │             ├─ _logLine
    │             └─ _logTests
    │                    ├─ _logTest
    │                    │      ├─ _getIcon
    │                    │      └─ formatTime
    │                    └─ _logTodoOrPendingTest
    │
    └─ jest-util
           ├─ formatTime
           └─ specialChars.ICONS
```

### データフロー図

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

TestResult ──────────────▶ onTestResult
       │                       │
       │                       ├─▶ testFinished (親クラス)
       │                       │
       │                       ├─▶ printTestFileHeader ────────▶ PASS/FAIL ヘッダー
       │                       │
       ▼                       │
TestResult.testResults ───▶ _logTestResults
       │                       │
       │                       ├─▶ groupTestsBySuites
       │                       │         │
       │                       │         └─▶ Suite ツリー構築
       │                       │
       │                       └─▶ _logSuite (再帰)
       │                                 │
       │                                 ├─▶ _logLine ──────────▶ describe 名
       │                                 │
       │                                 └─▶ _logTests
       │                                          │
       │                                          └─▶ _logTest ─▶ テスト結果行
       │
       └───────────────────▶ printTestFileFailureMessage ──────▶ エラー詳細
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| VerboseReporter.ts | `packages/jest-reporters/src/VerboseReporter.ts` | ソース | 詳細レポーター実装 |
| DefaultReporter.ts | `packages/jest-reporters/src/DefaultReporter.ts` | ソース | 親クラス |
| BaseReporter.ts | `packages/jest-reporters/src/BaseReporter.ts` | ソース | 基底クラス |
| types.ts | `packages/jest-reporters/src/types.ts` | ソース | 型定義 |
| index.ts | `packages/jest-reporters/src/index.ts` | ソース | エクスポート定義 |
