# 機能設計書 100-Test

## 概要

本ドキュメントは、Julia標準ライブラリのTestモジュールの設計を記述する。単体テストフレームワークとして、テストマクロ（`@test`, `@test_throws`, `@testset`）、テスト結果の集約・報告、テスト実行制御（failfast、verbose）を提供する機能である。

### 本機能の処理概要

**業務上の目的・背景**：ソフトウェア品質を保証するため、Juliaには標準で単体テストフレームワークが組み込まれている。Testモジュールは、テストケースの記述、テストセットによるグルーピング、テスト結果の集約と報告、エラー時のバックトレース取得と表示を提供する。

**機能の利用シーン**：パッケージのテストスイート実行（`Pkg.test()`）、REPL上での対話的テスト、CI/CDパイプラインでの自動テスト、`@test`マクロによるアサーション、`@testset`によるテストのグルーピングと階層化。

**主要な処理内容**：
1. `@test`マクロ：式の評価とPass/Failの判定
2. `@test_throws`マクロ：例外発生の検証
3. `@test_broken`マクロ：既知の不具合テスト
4. `@test_skip`マクロ：テストのスキップ
5. `@test_warn`/`@test_nowarn`マクロ：警告の検証
6. `@test_logs`マクロ：ログ出力の検証
7. `@test_deprecated`マクロ：非推奨警告の検証
8. `@testset`マクロ：テストのグルーピング、結果集約、サマリー表示
9. `@inferred`マクロ：型推論の検証
10. `detect_ambiguities`/`detect_unbound_args`/`detect_closure_boxes`：コード品質検査
11. テスト結果型：Pass, Fail, Error, Broken の4種類
12. テストロガー（TestLogger）：ログテスト用ロガー
13. 汎用テスト型：GenericString, GenericSet, GenericDict, GenericArray

**関連システム・外部連携**：Random（テストの乱数シード管理）、InteractiveUtils（型推論チェック）、Serialization（分散テスト対応）、Base.ScopedValues（スコープ付き値管理）。

**権限による制御**：特にない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | ライブラリ機能のため関連画面なし |

## 機能種別

テストフレームワーク

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| expr | Expr | Yes | テスト対象の式（@testマクロ引数） | 有効なJulia式 |
| exception_type | Type | No | 期待される例外型（@test_throwsの引数） | Exception型であること |
| testset_name | String | No | テストセット名 | 任意の文字列 |

環境変数による制御：

| 環境変数 | 説明 | デフォルト |
|---------|------|----------|
| JULIA_TEST_VERBOSE | 詳細テスト出力の有効化 | false |
| JULIA_TEST_FAILFAST | 最初の失敗で停止 | false |
| JULIA_TEST_RECORD_PASSES | Passテストの記録 | false |

### 入力データソース

- テストコード（Juliaソースファイル）
- 環境変数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| テスト結果 | Result(Pass/Fail/Error/Broken) | 各テストの結果 |
| テストサマリー | - | テストセットの集約結果（pass/fail/error/broken/total数） |

### 出力先

標準出力（テスト結果サマリー）、TestSetExceptionスロー（テスト失敗時）

## 処理フロー

### 処理シーケンス

```
1. @testset展開
   ├─ テストセットオブジェクト作成（DefaultTestSet）
   ├─ テスト実行環境のセットアップ（RNGシード設定）
   └─ テスト本体の実行
2. @test展開
   ├─ 式の評価
   ├─ 結果の判定（Pass/Fail/Error）
   ├─ バックトレースのスクラビング
   └─ テストセットへの結果記録
3. テスト結果集約
   ├─ 各テストセットの結果カウント
   ├─ ネストされたテストセットの再帰集約
   └─ サマリー表示（verbose/通常モード）
4. テスト失敗時の処理
   ├─ failfast: 即座に停止
   └─ 通常: 結果を記録して続行、最後にTestSetException
```

### フローチャート

```mermaid
flowchart TD
    A["@testset 開始"] --> B[DefaultTestSet作成]
    B --> C[RNGシード設定]
    C --> D["@test式の実行"]
    D --> E{結果判定}
    E -->|true| F[Pass記録]
    E -->|false| G[Fail記録]
    E -->|例外| H[Error記録]
    F --> I{failfast?}
    G --> I
    H --> I
    I -->|Yes and Fail/Error| J[即座に停止]
    I -->|No| K[次のテスト]
    K --> D
    D --> L["@testset 終了"]
    L --> M[結果集約]
    M --> N{失敗あり?}
    N -->|Yes| O[TestSetException]
    N -->|No| P[サマリー表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-100-01 | デフォルトテストセット | タスクレベルのデフォルトテストセットが存在し、最初の失敗でスロー | @testsetなしで@testを使用 |
| BR-100-02 | failfast制御 | JULIA_TEST_FAILFAST=trueで最初のFail/Errorで即停止 | 環境変数設定時 |
| BR-100-03 | verbose出力 | JULIA_TEST_VERBOSE=trueでテストセット入退出メッセージを表示 | 環境変数設定時 |
| BR-100-04 | pass記録制御 | デフォルトではPassテストの詳細を記録しない（メモリ節約） | JULIA_TEST_RECORD_PASSES |
| BR-100-05 | バックトレーススクラビング | テストフレームワーク内部のスタックフレームを除外してユーザコードのみ表示 | テスト失敗時 |

### 計算ロジック

- `scrub_backtrace`: `do_test`/`do_test_throws`の位置から`@testset`の`macro expansion`までのフレームを抽出
- `test_location`: テスト失敗位置の特定（インライン関数への対応含む）

## データベース操作仕様

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | TestSetException | テストセット内にFail/Errorが存在 | テストセット終了時にスロー |
| - | Error結果 | テスト式の評価中に予期せぬ例外 | Error結果として記録、バックトレース付き |
| - | Broken結果 | @test_brokenのテストがPassした場合 | Broken(UnexpectedPass)として記録 |

### リトライ仕様

テストのリトライ機構は組み込まれていない。

## トランザクション仕様

該当なし

## パフォーマンス要件

- Passテストの詳細記録をデフォルトで無効化してメモリ使用量を抑制
- OncePerProcessによるglobal_fail_fastの遅延評価

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

特になし（テスト専用機能）

## 備考

- GenericString, GenericSet, GenericDict, GenericArray は抽象インターフェースのテスト用に提供される汎用型
- TestLogger はログ出力テスト用の専用ロガー
- detect_ambiguities()はモジュール内のメソッド曖昧性を検出するユーティリティ

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Test.jl | `stdlib/Test/src/Test.jl` | Result型階層（Pass, Fail, Error, Broken）、DefaultTestSet型、AbstractTestSet |

**読解のコツ**: Testモジュールはマクロが多いため、`@macroexpand`で展開結果を確認しながら読むとよい。`@test expr`は内部的に`do_test`関数に変換され、結果判定とバックトレース処理が行われる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Test.jl | `stdlib/Test/src/Test.jl` | @testマクロの定義、@testsetマクロの定義 |

**主要処理フロー**:
1. **41-43行目**: `global_fail_fast` - OncePerProcessで環境変数から遅延読み込み
2. **48-51行目**: `ip_has_file_and_func` - バックトレースフィルタリング
3. **53-96行目**: バックトレーススクラビング関数群

#### Step 3: バックトレース処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Test.jl | `stdlib/Test/src/Test.jl` | scrub_backtrace, test_location, test_callsite |

**主要処理フロー**:
- **53-59行目**: `test_location` - file_tsとfile_tからテスト位置を特定
- **61-84行目**: `test_callsite` - @testと@testsetのスタック位置を検出
- **88-96行目**: `scrub_backtrace` - do_test以降のフレームを抽出

#### Step 4: ログテストを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | logging.jl | `stdlib/Test/src/logging.jl` | TestLogger実装、@test_logsマクロ |

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

```
@testset "name" begin ... end
    +-- DefaultTestSet("name")
    +-- push_testset(ts)
    +-- [テスト本体実行]
    |       +-- @test expr
    |       |       +-- do_test(result, ...)
    |       |       |       +-- record(ts, Pass/Fail/Error)
    |       |       +-- scrub_backtrace()
    |       |
    |       +-- @test_throws ExType expr
    |       |       +-- do_test_throws(result, ...)
    |       |
    |       +-- @test_logs (:info, "msg") expr
    |               +-- TestLogger
    |
    +-- pop_testset()
    +-- finish(ts)
            +-- 結果集約
            +-- サマリー表示
            +-- [失敗時] throw(TestSetException)
```

### データフロー図

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

テスト式 ──────────────────> @test → do_test ────────────> Result(Pass/Fail/Error)
                                |
例外型 + テスト式 ─────────> @test_throws → do_test_throws > Result(Pass/Fail)
                                |
テストセット ──────────────> DefaultTestSet ─────────────> results[]
                                |
環境変数 ──────────────────> global_fail_fast ────────────> Bool
  JULIA_TEST_FAILFAST           |
  JULIA_TEST_VERBOSE            |
                                |
results[] ─────────────────> finish(ts) ─────────────────> サマリー出力
                                                            TestSetException
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Test.jl | `stdlib/Test/src/Test.jl` | ソース | テストフレームワークの中核実装 |
| logging.jl | `stdlib/Test/src/logging.jl` | ソース | TestLogger、@test_logsマクロ |
| precompile.jl | `stdlib/Test/src/precompile.jl` | ソース | プリコンパイル用コード |
