# 画面設計書 2-test

## 概要

本ドキュメントは、Bun CLIの`test`コマンドの設計仕様を記述する。`bun test`コマンドは、Bunに内蔵されたJest互換のテストランナーを使用して、ユニットテストを実行する機能を提供する。

### 本画面の処理概要

`bun test`コマンドは、JavaScript/TypeScriptで記述されたテストファイルを高速に実行し、結果をレポートする。Jest互換のAPIを提供し、既存のJestテストコードをそのまま実行可能。

**業務上の目的・背景**：ソフトウェア開発において、テストは品質保証の要である。従来のJest/Vitestと比較して大幅に高速なテスト実行を実現し、開発者のフィードバックサイクルを短縮する。また、Jest互換のAPIにより、既存プロジェクトからの移行コストを最小化する。

**画面へのアクセス方法**：ターミナルから以下のコマンドで実行する。
- `bun test` - カレントディレクトリ以下のテストファイルを実行
- `bun test <file>` - 特定のテストファイルを実行
- `bun test -t "pattern"` - パターンにマッチするテストのみ実行

**主要な操作・処理内容**：
1. テストファイルの検出（*.test.ts, *.spec.ts等）
2. describe/test/itブロックの解析と実行
3. expect()によるアサーション評価
4. スナップショットテストの実行と比較
5. モック/スパイ機能の提供
6. コードカバレッジの計測（オプション）
7. JUnit形式レポートの出力（オプション）

**画面遷移**：
- エントリーポイント：`bun` コマンドから直接遷移
- 遷移先：テスト完了後はターミナルに制御を返す
- 関連コマンド：`bun run`（ファイル実行）

**権限による表示制御**：特になし。ファイルシステムの読み取り権限に依存。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | bun test | 主機能 | テストランナーの起動とテストファイルの実行 |
| 48 | Jest互換テスト | 主機能 | describe、test、expectなどのJest互換APIによるテスト実行 |
| 49 | スナップショットテスト | 補助機能 | toMatchSnapshot、toMatchInlineSnapshotによるスナップショット比較 |
| 50 | モック機能 | 補助機能 | mock、spyOnによる関数やモジュールのモック処理 |
| 51 | コードカバレッジ | 補助機能 | --coverageオプションによるカバレッジレポート生成 |
| 52 | Watchモード | 補助機能 | --watchオプションによるファイル変更時の自動テスト再実行 |
| 53 | JUnitレポート | 補助機能 | --junitオプションによるJUnit形式レポート出力 |
| 54 | DOMテスト | 補助機能 | happy-domによるブラウザ環境シミュレーション |

## 画面種別

コマンドラインインターフェース（CLI）- テスト実行コマンド

## URL/ルーティング

コマンドラインパターン:
- `bun test [flags] [file-patterns...] [-- args...]`

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| file-patterns | string[] | No | テストファイルのパターン（glob対応） |
| -t / --test-name-pattern | string | No | テスト名のフィルタパターン |
| --timeout | number | No | テストタイムアウト（デフォルト5000ms） |
| --rerun-each | number | No | 各テストの繰り返し回数 |
| --bail | number | No | 失敗時に停止するまでの失敗数 |
| --watch | flag | No | ファイル変更時に自動再実行 |
| --coverage | flag | No | コードカバレッジを計測 |
| --update-snapshots | flag | No | スナップショットを更新 |
| --junit | string | No | JUnit形式レポートの出力先 |
| --only | flag | No | .onlyが付いたテストのみ実行 |
| --todo | flag | No | .todoテストも実行 |
| --preload | string[] | No | テスト前にロードするモジュール |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| テスト結果 | text | 各テストの成功/失敗状態 |
| サマリー | text | 合計テスト数、成功数、失敗数、スキップ数 |
| エラー詳細 | text | 失敗したテストのスタックトレースと差分 |
| カバレッジレポート | text/file | コードカバレッジの統計（オプション） |
| JUnitレポート | file | JUnit形式XMLファイル（オプション） |
| exit code | number | 0: 全テスト成功、1: 失敗あり |

## 表示項目

| 項目名 | 表示条件 | 説明 |
|--------|----------|------|
| テストファイル名 | 常時 | 実行中のテストファイル |
| テスト名 | 常時 | describe/testブロック名 |
| 実行結果マーカー | 常時 | ✓（成功）、✗（失敗）、»（スキップ）、✎（TODO） |
| 実行時間 | 常時 | 各テストの実行時間（ms） |
| エラーメッセージ | 失敗時 | 期待値と実際値の差分 |
| サマリー統計 | 完了時 | pass/fail/skip/todoの件数 |

## イベント仕様

### 1-テスト実行

ユーザーが`bun test`を実行した場合の処理フロー：

1. コマンドライン引数を解析
2. テストファイルの検出（glob パターンマッチ）
3. 各テストファイルに対してJavaScriptCore VMで実行
4. describe/test/itブロックを解析・登録
5. beforeAll/beforeEach フックの実行
6. テストケースの実行とexpectによるアサーション評価
7. afterEach/afterAll フックの実行
8. 結果の集計とレポート出力
9. 終了コードを返却（0: 成功、1: 失敗）

### 2-スナップショットテスト

toMatchSnapshot/toMatchInlineSnapshot使用時の処理フロー：

1. スナップショットファイル（__snapshots__/*.snap）の読み込み
2. 実際の値とスナップショットの比較
3. 差分がある場合はエラー表示
4. --update-snapshots時はスナップショットファイルを更新

### 3-コードカバレッジ

--coverageオプション指定時の処理フロー：

1. V8カバレッジAPIの有効化
2. テスト実行中のコード実行を追跡
3. 実行完了後にカバレッジデータを集計
4. ファイル別/行別のカバレッジ率を計算
5. レポートを出力

## データベース更新仕様

本コマンドはデータベースを使用しない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|----------|
| TEST_PASS | success | ✓ {test-name} | テスト成功 |
| TEST_FAIL | error | ✗ {test-name} | テスト失敗 |
| TEST_SKIP | info | » {test-name} | テストスキップ |
| TEST_TODO | info | ✎ {test-name} | TODOテスト |
| SUMMARY | info | {pass} pass, {fail} fail, {skip} skip | テスト完了時 |
| TIMEOUT | error | Test "{name}" timed out after {ms}ms | タイムアウト発生 |
| NO_TESTS | warning | 0 tests found | テストが見つからない |

## 例外処理

| 例外種別 | 発生条件 | 処理内容 |
|---------|----------|---------|
| テストファイル不在 | パターンにマッチするファイルがない | 警告メッセージを表示 |
| 構文エラー | テストファイルの構文エラー | パースエラーを表示し該当ファイルをスキップ |
| タイムアウト | テストが制限時間を超過 | タイムアウトエラーとして失敗扱い |
| アサーション失敗 | expect()の評価が失敗 | 差分を表示しテストを失敗として記録 |

## 備考

- BunのテストランナーはJest互換のAPIを提供
- happy-domによるDOM環境シミュレーションをサポート
- --bailオプションで早期終了が可能
- --watchモードでTDD開発をサポート

---

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

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

### 推奨読解順序

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

テスト実行に使用されるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cli.zig | `src/cli.zig` | TestOptions構造体の定義を確認（行340-363） |
| 1-2 | test_command.zig | `src/cli/test_command.zig` | JunitReporter構造体とMetrics |

**読解のコツ**: TestOptionsにはtimeout、coverage、reporters等の設定が含まれる。JunitReporterはXML形式のレポート生成を担当。

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

テストコマンドの起点となるファイル・関数を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | test_command.zig | `src/cli/test_command.zig` | TestCommand構造体 |

**主要処理フロー**:
1. **JunitReporter** - JUnit形式レポートの生成クラス
2. **escapeXml関数（行4-41）** - XML特殊文字のエスケープ処理
3. **fmtStatusTextLine関数（行42-62）** - テスト結果のフォーマット
4. **writeTestCase関数（行372-500+）** - テストケース結果のXML出力

#### Step 3: テスト結果表示処理を理解する

テスト結果の表示とレポート生成処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | test_command.zig | `src/cli/test_command.zig` | writeTestStatusLine関数 |
| 3-2 | test_command.zig | `src/cli/test_command.zig` | JunitReporter.writeTestCase関数 |

**主要処理フロー**:
- **行64-68**: `writeTestStatusLine` - ステータス行の出力
- **行73-171**: `JunitReporter` - JUnitレポートの初期化と構造
- **行266-329**: `beginTestSuite` / `endTestSuite` - テストスイートの開始・終了
- **行372-500+**: `writeTestCase` - 各テストケースの結果出力

#### Step 4: Jest互換API実装を理解する

Jest互換のdescribe/test/expect APIの実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | bun_test.zig | `src/bun.js/bun_test.zig` | Jest互換APIの実装（推定） |

**読解のコツ**: JavaScriptCore側でdescribe/test/expect等のグローバル関数が定義される。Zig側ではそれらのコールバックを処理。

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

```
TestCommand.exec()
    |
    +-- Arguments.parse() (テストオプション解析)
    |
    +-- テストファイル検出 (glob pattern)
    |
    +-- 各テストファイルに対して:
    |       |
    |       +-- JavaScriptCore VM起動
    |       |
    |       +-- describe/test ブロック解析
    |       |
    |       +-- beforeAll/beforeEach 実行
    |       |
    |       +-- テストケース実行
    |       |       +-- expect() アサーション
    |       |
    |       +-- afterEach/afterAll 実行
    |
    +-- JunitReporter.writeTestCase() (結果出力)
    |
    +-- サマリー出力
    |
    +-- exit code 返却
```

### データフロー図

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

コマンドライン引数 -----> Arguments.parse() -----> TestOptions
        |
        v
テストファイル群 -------> glob pattern match -----> ファイルリスト
        |
        v
各テストファイル -------> JavaScriptCore VM -----> テスト実行
        |
        v
expect() 呼び出し ------> アサーション評価 -------> pass/fail
        |
        v
                        JunitReporter ---------> XML/Console出力
                              |
                              v
                        Summary ---------> exit code (0/1)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| test_command.zig | `src/cli/test_command.zig` | ソース | testコマンドのメイン実装、JUnitレポーター |
| cli.zig | `src/cli.zig` | ソース | TestOptions構造体定義 |
| bun_test.zig | `src/bun.js/bun_test.zig` | ソース | Jest互換API実装 |
| expect.zig | `src/bun.js/expect.zig` | ソース | expectアサーション実装 |
| snapshot.zig | `src/bun.js/snapshot.zig` | ソース | スナップショットテスト実装（推定） |
