# 帳票設計書 12-cobertura

## 概要

本ドキュメントは、Jestのカバレッジレポート機能におけるCobertura XML形式レポートの設計仕様を定義する。istanbul-reportsライブラリを使用し、CI/CDツールとの連携に適したCobertura形式のカバレッジレポートを生成する機能について詳述する。

### 本帳票の処理概要

CoberturaカバレッジレポートはJestテスト実行時に収集されたコードカバレッジ情報を、Cobertura XML形式で出力する帳票である。この形式はJenkins、Azure DevOps、GitLab CI/CDなど多くのCI/CDツールで標準的にサポートされており、カバレッジトレンドの追跡やレポート統合に使用される。

**業務上の目的・背景**：CI/CDパイプラインにおいてカバレッジ情報を自動収集・可視化するために使用される。Cobertura形式は業界標準のXMLスキーマに準拠しており、異なるツール間でのカバレッジデータの相互運用性を確保する。Jenkins Cobertura Pluginなどのツールと連携することで、ビルドごとのカバレッジ推移を追跡できる。

**帳票の利用シーン**：Jenkins等のCIサーバーでのカバレッジレポート生成、Azure DevOpsでのコードカバレッジ統合、SonarQubeへのカバレッジデータインポート、GitLab CI/CDでのカバレッジバッジ生成において利用される。

**主要な出力内容**：
1. XMLヘッダーとDTD参照
2. coverage要素（line-rate、branch-rate、timestamp等の属性）
3. packages要素（パッケージ/ディレクトリ単位のカバレッジ情報）
4. classes要素（ファイル単位のカバレッジ情報）
5. lines要素（行単位のカバレッジ情報）

**帳票の出力タイミング**：`jest --coverage` コマンド実行時、または `collectCoverage: true` 設定時にテスト完了後に自動生成される。`coverageReporters` に `'cobertura'` を含めることで出力される。

**帳票の利用者**：DevOpsエンジニア、CI/CD管理者、品質管理チーム、開発リーダー

## 帳票種別

カバレッジデータレポート（CI/CD連携用XML）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | CLI（コマンドライン） | - | `jest --coverage` コマンド実行 |
| - | 設定ファイル | jest.config.js | `coverageReporters: ['cobertura']` 設定 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | XML（Cobertura DTD準拠） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | `cobertura-coverage.xml` |
| 出力方法 | ファイルシステムへの出力 |
| 文字コード | UTF-8 |

### XML固有設定

| 項目 | 内容 |
|-----|------|
| 出力ディレクトリ | `{coverageDirectory}/` |
| XMLバージョン | 1.0 |
| DTD | coverage-04.dtd（Cobertura標準） |
| 名前空間 | なし |

## 帳票レイアウト

### レイアウト概要

Cobertura XMLは階層構造を持つXMLドキュメントとして構成される。

```xml
<?xml version="1.0" ?>
<!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">
<coverage>
    <packages>
        <package>
            <classes>
                <class>
                    <methods>...</methods>
                    <lines>...</lines>
                </class>
            </classes>
        </package>
    </packages>
</coverage>
```

### coverage要素（ルート）

| No | 属性名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | line-rate | 全体の行カバレッジ率 | CoverageSummary.lines.pct / 100 | 0.0〜1.0の小数 |
| 2 | branch-rate | 全体の分岐カバレッジ率 | CoverageSummary.branches.pct / 100 | 0.0〜1.0の小数 |
| 3 | lines-covered | カバーされた行数 | CoverageSummary.lines.covered | 整数 |
| 4 | lines-valid | 有効な行数 | CoverageSummary.lines.total | 整数 |
| 5 | branches-covered | カバーされた分岐数 | CoverageSummary.branches.covered | 整数 |
| 6 | branches-valid | 有効な分岐数 | CoverageSummary.branches.total | 整数 |
| 7 | timestamp | 生成タイムスタンプ | Date.now() | UNIXタイムスタンプ（ミリ秒） |
| 8 | complexity | 複雑度 | 計算値 | 整数 |
| 9 | version | Coberturaバージョン | 固定値 | 文字列 |

### package要素

| No | 属性名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | name | パッケージ名（ディレクトリパス） | ファイルパスから抽出 | ドット区切り文字列 |
| 2 | line-rate | パッケージの行カバレッジ率 | 集計値 | 0.0〜1.0の小数 |
| 3 | branch-rate | パッケージの分岐カバレッジ率 | 集計値 | 0.0〜1.0の小数 |
| 4 | complexity | パッケージの複雑度 | 集計値 | 整数 |

### class要素

| No | 属性名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | name | クラス/ファイル名 | FileCoverage.path | ファイル名 |
| 2 | filename | ファイルの相対パス | FileCoverage.path | パス文字列 |
| 3 | line-rate | ファイルの行カバレッジ率 | FileCoverage.toSummary() | 0.0〜1.0の小数 |
| 4 | branch-rate | ファイルの分岐カバレッジ率 | FileCoverage.toSummary() | 0.0〜1.0の小数 |
| 5 | complexity | ファイルの複雑度 | 計算値 | 整数 |

### line要素

| No | 属性名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | number | 行番号 | FileCoverage.statementMap | 整数 |
| 2 | hits | 実行回数 | FileCoverage.s | 整数 |
| 3 | branch | 分岐の有無 | FileCoverage.branchMap | true/false |
| 4 | condition-coverage | 分岐カバレッジ詳細 | FileCoverage.b | パーセント表記 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| collectCoverage | カバレッジ収集が有効であること | Yes |
| coverageReporters | `'cobertura'` が含まれていること | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | パッケージ名 | 昇順（アルファベット順） |
| 2 | ファイル名 | 昇順（アルファベット順） |
| 3 | 行番号 | 昇順（数値順） |

### 改ページ条件

N/A（XMLのため改ページは発生しない）

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

### 参照テーブル一覧

本帳票はデータベースを使用せず、テスト実行時に収集されたカバレッジデータ（メモリ上のCoverageMap）を参照する。

| データソース名 | 用途 | 取得方法 |
|---------------|------|---------|
| CoverageMap | カバレッジ情報全体 | `istanbulCoverage.createCoverageMap()` |
| FileCoverage | ファイル単位のカバレッジ | `map.fileCoverageFor(path)` |
| CoverageSummary | サマリー情報 | `fileCoverage.toSummary()` |

### データ構造詳細

#### FileCoverage

| フィールド | 説明 | 型 |
|-----------|------|-----|
| path | ファイルパス | string |
| statementMap | ステートメント位置マップ | `{[id]: Location}` |
| s | ステートメント実行回数 | `{[id]: number}` |
| branchMap | 分岐位置マップ | `{[id]: BranchMapping}` |
| b | 分岐実行回数 | `{[id]: number[]}` |
| fnMap | 関数位置マップ | `{[id]: FunctionMapping}` |
| f | 関数実行回数 | `{[id]: number}` |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| line-rate | `lines.covered / lines.total` | 小数点以下保持 | total=0の場合は1.0 |
| branch-rate | `branches.covered / branches.total` | 小数点以下保持 | total=0の場合は1.0 |
| complexity | 循環的複雑度の合計 | なし | istanbul-reportsで計算 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[テスト実行完了] --> B[CoverageReporter.onRunComplete]
    B --> C[カバレッジデータ収集]
    C --> D[V8/Babel プロバイダーからデータ変換]
    D --> E[istanbulReports.create cobertura 呼び出し]
    E --> F[reportContext生成]
    F --> G[XMLドキュメント構築]
    G --> H[cobertura-coverage.xml出力]
    H --> I[終了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 出力失敗 | ディレクトリ書き込み権限なし | `Failed to write coverage reports: ERROR: ...` | coverageDirectory の権限確認 |
| XML生成エラー | 不正なカバレッジデータ | スタックトレース付きエラー | カバレッジデータの整合性確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数千ファイル |
| 目標出力時間 | 大規模プロジェクトで数秒 |
| 同時出力数上限 | 1（シングルプロセスで出力） |

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

- 出力されるXMLにはファイルパス情報が含まれるため、ディレクトリ構造が公開される可能性がある
- CI/CD環境でのアーティファクト公開時は、センシティブなパス情報が含まれていないことを確認
- XMLパーサーの脆弱性（XXE等）に注意が必要な場合は、消費側ツールの設定を確認

## 備考

- Coberturaレポートはデフォルトの `coverageReporters` には含まれていないため、明示的に設定が必要
- `coverageDirectory` で出力先を変更可能（デフォルト: `coverage/`）
- Jenkinsとの連携にはJenkins Cobertura Pluginが必要
- Azure DevOpsでは標準でCobertura形式をサポート

---

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

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

### 推奨読解順序

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

Coberturaレポート生成に使用されるカバレッジデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Config.ts | `packages/jest-types/src/Config.ts` | CoverageReporterName型の定義（行132） |

**読解のコツ**: `CoverageReporterName`は`keyof ReportOptions`として定義されており、istanbul-reportsでサポートされているすべてのレポーター名を含む。coberturaもこの一部として含まれる。

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

カバレッジレポート生成のエントリーポイントを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CoverageReporter.ts | `packages/jest-reporters/src/CoverageReporter.ts` | onRunCompleteメソッドでレポート生成が開始される |

**主要処理フロー**:
1. **行70-107**: `onRunComplete`メソッドでカバレッジ結果を処理
2. **行78**: `coverageReporters`配列を取得（coberturaが含まれる場合に処理）
3. **行83-94**: 各レポーターに対して`istanbulReports.create(reporter, options).execute(reportContext)`を呼び出し

#### Step 3: レポートコンテキスト生成を理解する

Coberturaレポートに渡されるコンテキストの生成プロセスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CoverageReporter.ts | `packages/jest-reporters/src/CoverageReporter.ts` | _getCoverageResultメソッド（行437-516） |

**主要処理フロー**:
- **行498-504**: reportContext生成時にcoverageDirectoryが設定される
- **行500**: `dir: this._globalConfig.coverageDirectory`でXML出力先が決定

#### Step 4: 設定のデフォルト値を理解する

Coberturaレポートの設定方法を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Defaults.ts | `packages/jest-config/src/Defaults.ts` | デフォルトのcoverageReporters（行28） |

**主要処理フロー**:
- **行28**: デフォルト値は `['json', 'text', 'lcov', 'clover']` でcoberturaは含まれない

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

```
jest --coverage
    │
    ├─ TestScheduler
    │      └─ CoverageReporter.onRunComplete()
    │             │
    │             ├─ _addUntestedFiles()（未テストファイルのカバレッジ追加）
    │             │
    │             ├─ _getCoverageResult()
    │             │      ├─ V8/Babelプロバイダーからデータ変換
    │             │      └─ istanbulReport.createContext()
    │             │
    │             ├─ istanbulReports.create('cobertura', options)
    │             │      └─ .execute(reportContext)
    │             │             └─ cobertura-coverage.xmlを出力
    │             │
    │             └─ _checkThreshold()（閾値チェック）
    │
    └─ coverage/cobertura-coverage.xml ファイル出力
```

### データフロー図

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

テスト実行結果         CoverageReporter              coverage/
      │                      │                              │
V8Coverage ────────▶ _getCoverageResult() ─────▶ istanbul-reports
      │                      │                    (cobertura reporter)
BabelCoverage ─────▶ CoverageMap構築                       │
      │                      │                              │
FileCoverage ──────▶ パッケージ/クラス/行に変換 ───▶ cobertura-coverage.xml
                             │
                    XML構造生成
                             │
                    ファイル出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CoverageReporter.ts | `packages/jest-reporters/src/CoverageReporter.ts` | ソース | カバレッジレポート生成の主要ロジック |
| Config.ts | `packages/jest-types/src/Config.ts` | ソース | 型定義（CoverageReporterName等） |
| Defaults.ts | `packages/jest-config/src/Defaults.ts` | ソース | デフォルト設定値 |
| CoverageReporter.test.js | `packages/jest-reporters/src/__tests__/CoverageReporter.test.js` | テスト | CoverageReporterのユニットテスト |
| Configuration.md | `docs/Configuration.md` | ドキュメント | coverageReportersの設定説明 |
