# 機能設計書: テスト実行 (No.22)

## 1. 機能概要

### 1.1 機能名
テスト実行 (koch.nim tests / testament)

### 1.2 機能説明
Nimコンパイラおよび標準ライブラリのテストスイートを実行する機能。Testamentツールを使用して、コンパイル、実行、拒否テストなど複数種類のテストケースを自動実行し、結果を報告する。Azure PipelinesなどのCI/CD環境との統合もサポート。

### 1.3 関連画面
- CLI（コマンドラインインターフェース）

## 2. 機能詳細

### 2.1 入力
| 項目 | 型 | 必須 | 説明 |
|------|-----|------|------|
| command | string | Yes | all, cat, pattern, run, html のいずれか |
| arguments | string | No | コマンド引数（カテゴリ名、パターン、ファイルパス等） |
| --targets | string | No | ターゲット指定（c cpp js objc） |
| --nim | string | No | 使用するNimコンパイラのパス |
| --verbose | bool | No | 詳細出力モード |
| --simulate | bool | No | ドライランモード |

### 2.2 処理フロー
1. **初期化**
   - azure.init() でAzure Pipelines統合を初期化
   - backend.open() でデータベース接続を開始

2. **コマンド解析**
   - initOptParser() でコマンドラインオプションを解析
   - targets, nim, verbose等のオプションを設定

3. **テスト実行**
   - **all**: 全カテゴリを並列実行
   - **cat/category**: 指定カテゴリのテストを実行
   - **pcat**: カテゴリを並列モードで実行（joinableテスト除外）
   - **pattern**: パターンマッチングでテストを選択
   - **run**: 単一テストファイルを実行
   - **html**: 結果HTMLを生成

4. **テスト評価**
   - TSpec構造体でテスト仕様を解析
   - callNimCompiler() でコンパイル
   - 実行結果を期待値と比較

5. **結果報告**
   - TResults構造体に結果を集計
   - Azure/AppVeyorへの結果送信
   - HTML/コンソール出力

### 2.3 出力
| 項目 | 型 | 説明 |
|------|-----|------|
| コンソール出力 | string | テスト結果サマリー |
| testresults.html | file | HTML形式の結果レポート |
| 終了コード | int | 0=成功, 1=失敗 |

### 2.4 エラーハンドリング
| エラー条件 | 処理 |
|------------|------|
| コンパイルエラー | reBuildFailed を記録 |
| 実行時エラー | reOutputsDiffer 等を記録 |
| タイムアウト | reTimeout を記録 |
| 終了コード不一致 | reExitcodesDiffer を記録 |

## 3. ビジネスルール

### 3.1 テストアクション
| アクション | 説明 |
|------------|------|
| actionCompile | コンパイルが成功することを検証 |
| actionRun | コンパイル＆実行し、出力を検証 |
| actionReject | コンパイルが特定エラーで失敗することを検証 |

### 3.2 結果列挙型 (TResultEnum)
| 値 | 説明 |
|----|------|
| reSuccess | テスト成功 |
| reDisabled | テスト無効化 |
| reJoined | メガテストに統合済み |
| reBuildFailed | ビルド失敗 |
| reNimcCrash | コンパイラクラッシュ |
| reOutputsDiffer | 出力不一致 |
| reExitcodesDiffer | 終了コード不一致 |
| reTimeout | タイムアウト |

### 3.3 テスト仕様（TSpec）
テストファイルの先頭コメントから解析される仕様:
- `action`: compile, run, reject
- `output`: 期待される出力
- `exitcode`: 期待される終了コード
- `targets`: 対象ターゲット
- `matrix`: オプションの組み合わせ

## 4. 技術仕様

### 4.1 使用ライブラリ
- std/strutils, std/pegs, std/os, std/osproc
- std/streams, std/json, std/parseopt
- std/browsers, std/terminal, std/algorithm
- testament/backend, testament/specs, testament/azure

### 4.2 主要データ構造
```nim
type
  TResults = object
    total, passed, failedButAllowed, skipped: int
    data: string

  TTest = object
    name: string
    cat: Category
    options: string
    testArgs: seq[string]
    spec: TSpec
    startTime: float
    debugInfo: string

  TSpec = object
    action: TTestAction
    output: string
    exitCode: int
    targets: set[TTarget]
    # ... 他多数
```

### 4.3 キャッシュ戦略
```nim
proc nimcacheDir(filename, options: string, target: TTarget): string =
  let hashInput = options & $target
  result = "nimcache" / (filename & '_' & hashInput.getMD5)
```

### 4.4 並列実行
- `osproc.execProcesses()` で複数カテゴリを並列実行
- `--batch` オプションでテストを分割実行

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

### 5.1 推奨読解順序

#### 5.1.1 データ構造の理解
1. **testament.nim 86-100行目**: 主要型定義
   - Category, TResults, TTest の定義

2. **specs.nim**: TSpec型の完全な定義（別ファイル）
   - テスト仕様の解析ロジック

#### 5.1.2 エントリーポイント
3. **testament.nim 684-845行目**: main関数
   - コマンドライン解析と各コマンドへの分岐

4. **koch.nim 500-507行目**: tests関数
   ```nim
   proc tests(args: string) =
     nimexec "cc --opt:speed testament/testament"
     var testCmd = quoteShell(getCurrentDir() / "testament/testament".exe)
     testCmd.add " " & quoteShell("--nim:" & findNim())
     testCmd.add " " & (args|"all")
     let success = tryExec testCmd
   ```

#### 5.1.3 コア処理
5. **testament.nim 174-230行目**: callNimCompiler
   - コンパイラ呼び出しと出力解析

6. **testament.nim 489-570行目**: testSpecHelper
   - テスト実行のメインロジック

7. **testament.nim 603-620行目**: testSpec
   - テスト仕様に基づくテスト実行

### 5.2 読解のコツ

#### PEGパターン理解
```nim
pegLineError = peg"{[^(]*} '(' {\d+} ', ' {\d+} ') ' ('Error') ':' \s* {.*}"
pegOtherError = peg"'Error:' \s* {.*}"
```
- コンパイラエラー出力のパース用パターン

#### マクロ活用
- `maybeStyledEcho`: 色付き出力の条件分岐
- `ignoreStyleEcho`: スタイル引数を無視したecho

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

```
koch tests [args]
  |
  +-- nimexec("cc testament/testament")
  |
  +-- testament.exe --nim:path all [args]
        |
        +-- main()
              |
              +-- azure.init()
              +-- backend.open()
              |
              +-- [action="all"]
              |     +-- walkDir(testsDir)
              |     +-- osproc.execProcesses(cmds)  # 並列実行
              |
              +-- [action="cat"]
              |     +-- processCategory()
              |           +-- testSpec()
              |                 +-- testSpecHelper()
              |                       +-- callNimCompiler()
              |                       +-- execCmdEx2()  # 実行
              |
              +-- azure.finalize()
              +-- backend.close()
```

### 5.4 データフロー図

```
[テストファイル (.nim)]
        |
        v
[parseSpec()] --> [TSpec]
        |
        v
[makeTest()] --> [TTest]
        |
        v
[callNimCompiler()]
        |
        +-- [コンパイル出力] --> [TSpec (given)]
        v
[比較: expected vs given]
        |
        v
[TResults に集計]
        |
        v
[結果出力]
  +-- コンソール (PASS/FAIL)
  +-- HTML (testresults.html)
  +-- Azure/AppVeyor API
```

### 5.5 関連ファイル一覧

| ファイルパス | 種別 | 役割 |
|-------------|------|------|
| testament/testament.nim | メイン | テスト実行制御 |
| testament/specs.nim | データ | テスト仕様解析 |
| testament/backend.nim | データ | 結果データベース |
| testament/azure.nim | 統合 | Azure Pipelines連携 |
| testament/htmlgen.nim | 出力 | HTML結果生成 |
| testament/categories.nim | 制御 | カテゴリ処理 |
| koch.nim (500-507行目) | エントリ | kochからの呼び出し |
| tests/ | テストデータ | テストケース群 |

## 6. 変更履歴

| 日付 | 変更者 | 変更内容 |
|------|--------|----------|
| 2026-02-17 | Claude | 初版作成 |
