# 機能設計書 104-HeadlessXUnit

## 概要

本ドキュメントは、Avalonia UIフレームワークにおけるxUnitテストフレームワーク統合機能の機能設計書である。xUnitでのUIテストを実行するための基盤を提供する。

### 本機能の処理概要

HeadlessXUnitは、xUnitテストフレームワークとAvalonia Headlessプラットフォームを統合し、xUnitでAvaloniaアプリケーションのUIテストを実行可能にする。テストメソッドをAvalonia Dispatcherスレッドで実行し、非同期テストの適切なスレッド管理を提供する。

**業務上の目的・背景**：xUnitは.NETエコシステムで最も広く使用されているテストフレームワークの一つである。HeadlessXUnitにより、既存のxUnitテストインフラストラクチャを活用しながら、Avalonia UIコンポーネントの自動テストが可能になる。CIパイプラインでの統合テストや、UIコンポーネントの回帰テストを効率的に実行できる。

**機能の利用シーン**：
- Avalonia UIコンポーネントの単体テスト
- CIパイプラインでのUIテスト自動実行
- ビューモデルとビューの統合テスト
- UIイベントハンドラーのテスト
- スクリーンショットベースの回帰テスト

**主要な処理内容**：
1. xUnitテストフレームワークへのカスタムディスカバラー/エグゼキューターの登録
2. テストメソッドのAvalonia Dispatcher上での実行
3. HeadlessUnitTestSessionによるアプリケーションインスタンス管理
4. 非同期テストメソッドのawait対応
5. テストケース実行コンテキストの管理

**関連システム・外部連携**：
- xUnit v3テストフレームワーク
- Avalonia.Headlessプラットフォーム
- HeadlessUnitTestSession

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | テスト対象ウィンドウ | 仮想画面 | テスト実行時に作成されるHeadlessWindow |

## 機能種別

テストフレームワーク統合 / テスト実行基盤

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| AvaloniaFact属性 | Attribute | Yes | テストメソッドに付与 | - |
| AvaloniaTheory属性 | Attribute | No | パラメータ化テストに付与 | - |
| AvaloniaTestApplication属性 | Attribute | Yes | テストアプリケーションクラスを指定 | アセンブリレベル |

### 入力データソース

- テストメソッドの定義
- テストアプリケーションのAppBuilder設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| RunSummary | RunSummary | テスト実行結果のサマリー |
| TestResult | TestResult | 個別テストの結果 |

### 出力先

- xUnitテストランナー
- テスト結果レポート

## 処理フロー

### 処理シーケンス

```
1. テストディスカバリー
   └─ AvaloniaFactDiscovererがテストメソッドを検出
   └─ AvaloniaTestCaseを作成
2. テストフレームワーク初期化
   └─ AvaloniaTestFrameworkがカスタムディスカバラー/エグゼキューターを提供
3. テスト実行
   └─ HeadlessUnitTestSession.GetOrStartForAssemblyでセッション取得
   └─ AvaloniaTestCaseRunnerでテストケース実行
   └─ AvaloniaTestRunnerで実際のテストメソッド呼び出し
4. Dispatcherスレッドでテストメソッド実行
   └─ 非同期メソッドのawait対応
```

### フローチャート

```mermaid
flowchart TD
    A[テストディスカバリー] --> B[AvaloniaFactDiscoverer]
    B --> C[AvaloniaTestCase作成]
    C --> D[テスト実行フェーズ]
    D --> E[AvaloniaTestCaseRunner.Run]
    E --> F[HeadlessUnitTestSession取得]
    F --> G[AvaloniaTestRunner.Run]
    G --> H[Dispatcher.UIThread上でテスト実行]
    H --> I{テスト成功?}
    I -->|Yes| J[RunSummary更新]
    I -->|No| K[エラー記録]
    J --> L[次のテスト]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-104-1 | Dispatcherスレッド実行 | テストメソッドはAvalonia Dispatcherスレッドで実行 | 常時 |
| BR-104-2 | セッション再利用 | 同一アセンブリのテストは同じHeadlessUnitTestSessionを共有 | 常時 |
| BR-104-3 | 非同期サポート | async/awaitメソッドはDispatcher上で適切に継続 | 非同期テスト時 |

### 計算ロジック

特になし。

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

データベース操作なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SESSION_INIT_FAIL | Exception | HeadlessUnitTestSession初期化失敗 | テストアプリケーション設定確認 |
| DISPATCHER_ERROR | Exception | Dispatcherエラー | テストコードのスレッド安全性確認 |

### リトライ仕様

リトライなし（xUnitのリトライ機構を使用）。

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

トランザクションなし。

## パフォーマンス要件

- セッション再利用によるアプリケーション初期化オーバーヘッド削減
- テストの並列実行は同一Dispatcherで直列化

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

特になし。

## 備考

- xUnit v3をサポート
- AvaloniaTheoryでパラメータ化テストが可能

---

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

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

### 推奨読解順序

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

テスト属性とテストケースの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AvaloniaFact.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaFact.cs` | AvaloniaFactAttribute定義、XunitTestCaseDiscoverer属性 |
| 1-2 | AvaloniaTheoryAttribute.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaTheoryAttribute.cs` | パラメータ化テスト用属性 |

**読解のコツ**: AvaloniaFactAttributeはFactAttributeを継承し、CallerFilePath/CallerLineNumberでソース位置を追跡。

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

テストディスカバリーの起点を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AvaloniaFactDiscoverer.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaFactDiscoverer.cs` | AvaloniaFactのディスカバラー実装 |
| 2-2 | AvaloniaTestFramework.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaTestFramework.cs` | カスタムテストフレームワーク |

#### Step 3: テスト実行処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AvaloniaTestCaseRunner.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaTestCaseRunner.cs` | テストケースランナー実装 |

**主要処理フロー**:
- **18-45行目**: Run()でHeadlessUnitTestSessionを取得しコンテキスト作成
- **47-58行目**: RunTest()でAvaloniaTestRunner.Instance.Runを呼び出し

#### Step 4: セッション管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | HeadlessUnitTestSession.cs | `src/Headless/Avalonia.Headless/HeadlessUnitTestSession.cs` | テストセッション管理 |

**主要処理フロー**:
- GetOrStartForAssembly()でアセンブリごとにセッションを取得または作成
- DispatchCoreでDispatcher.UIThread上でテストを実行

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

```
xUnitテストランナー
    │
    ├─ AvaloniaTestFramework
    │      └─ CreateDiscoverer/CreateExecutor
    │
    ├─ AvaloniaFactDiscoverer
    │      └─ AvaloniaTestCase作成
    │
    └─ AvaloniaTestFrameworkExecutor
           └─ AvaloniaTestCaseRunner.Run
                  │
                  ├─ HeadlessUnitTestSession.GetOrStartForAssembly
                  │      └─ AppBuilder.SetupWithoutStarting
                  │
                  └─ AvaloniaTestRunner.Run
                         └─ Session.DispatchCore
                                └─ Dispatcher.UIThread.Invoke
```

### データフロー図

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

テストメソッド ─────────▶ AvaloniaFactDiscoverer ────────▶ AvaloniaTestCase
([AvaloniaFact])                                               │
                                                               ▼
AvaloniaTestCase ─────────▶ AvaloniaTestCaseRunner ────────▶ RunSummary
                                   │
                                   ▼
                          HeadlessUnitTestSession
                                   │
                                   ▼
                          Dispatcher.UIThread.Invoke ────────▶ TestResult
                                   │
                                   └─▶ テストメソッド実行
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AvaloniaFact.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaFact.cs` | ソース | Fact属性定義 |
| AvaloniaTheoryAttribute.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaTheoryAttribute.cs` | ソース | Theory属性定義 |
| AvaloniaFactDiscoverer.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaFactDiscoverer.cs` | ソース | Factディスカバラー |
| AvaloniaTheoryDiscoverer.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaTheoryDiscoverer.cs` | ソース | Theoryディスカバラー |
| AvaloniaTestCase.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaTestCase.cs` | ソース | テストケース定義 |
| AvaloniaTestCaseRunner.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaTestCaseRunner.cs` | ソース | テストケースランナー |
| AvaloniaTestRunner.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaTestRunner.cs` | ソース | テストランナー |
| AvaloniaTestFramework.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaTestFramework.cs` | ソース | テストフレームワーク |
| AvaloniaTestFrameworkExecutor.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaTestFrameworkExecutor.cs` | ソース | テストエグゼキューター |
| AvaloniaTestRunnerContext.cs | `src/Headless/Avalonia.Headless.XUnit/AvaloniaTestRunnerContext.cs` | ソース | ランナーコンテキスト |
