# 機能設計書 144-テストサポート

## 概要

本ドキュメントでは、Roslynのテストサポート（Testing）機能について設計を記載する。この機能は、コード内のテストメソッドを識別し、テストフレームワーク（xUnit、NUnit、MSTest）との連携を提供する。

### 本機能の処理概要

**業務上の目的・背景**：
現代のソフトウェア開発では、単体テストが重要な役割を果たしている。IDEはテストメソッドを識別し、テストランナーとの連携、CodeLensでのテスト結果表示、テスト実行ナビゲーションなどの機能を提供する必要がある。本機能は、xUnit、NUnit、MSTestといった主要テストフレームワークのテストメソッドを構文的に識別するための基盤を提供する。

**機能の利用シーン**：
- エディタ上でテストメソッドを識別してCodeLensに表示
- テスト実行時に対象メソッドを特定
- テスト結果からコード位置へのナビゲーション
- テストカバレッジ表示のための対象メソッド特定

**主要な処理内容**：
1. ドキュメント内のテストメソッド候補の検索
2. テストフレームワーク属性（[Fact]、[Test]、[TestMethod]等）の検出
3. 完全修飾テスト名とメソッドノードのマッチング
4. テスト範囲に交差するメソッドの特定

**関連システム・外部連携**：
- Visual Studioテストエクスプローラー
- CodeLens機能
- テストランナー（Test Adapter）

**権限による制御**：
特定の権限による制御は行わない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | テストエクスプローラー | 参照画面 | テスト一覧の表示元 |
| - | コードエディタ | 主画面 | テストメソッドのCodeLens表示 |

## 機能種別

コード分析 / テスト連携 / IDE機能

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 解析対象ドキュメント | null不可 |
| textSpan | TextSpan | Yes | 検索対象範囲 | 有効なスパン |
| fullyQualifiedTestName | string | No | マッチング対象のテスト名 | 空でないこと |

### 入力データソース

- ソースコードドキュメント
- テスト結果からの完全修飾テスト名

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| testMethods | ImmutableArray<SyntaxNode> | 検出されたテストメソッドノード |
| isMatch | bool | 完全修飾名とのマッチング結果 |

### 出力先

- CodeLens表示
- テストランナー連携

## 処理フロー

### 処理シーケンス

```
1. ドキュメント取得
   └─ 対象ドキュメントの構文木を取得
2. メソッド探索
   └─ 指定範囲内のメソッド宣言を走査
3. 属性チェック
   └─ 各テストフレームワークの属性名をチェック
4. テストメソッド判定
   └─ 属性が一致するメソッドをテストメソッドとして返却
```

### フローチャート

```mermaid
flowchart TD
    A[ドキュメント構文木取得] --> B[範囲内ノード走査]
    B --> C{メソッド宣言?}
    C -->|Yes| D[属性リスト取得]
    C -->|No| B
    D --> E{テスト属性あり?}
    E -->|Yes| F[テストメソッドとして追加]
    E -->|No| B
    F --> G{範囲内に他ノード?}
    G -->|Yes| B
    G -->|No| H[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-144-01 | xUnit属性 | Fact、Theory、FactAttribute、TheoryAttributeを認識 | xUnitテスト検出時 |
| BR-144-02 | NUnit属性 | Test、TestCase、TestCaseSource等を認識 | NUnitテスト検出時 |
| BR-144-03 | MSTest属性 | TestMethod、DataTestMethod等を認識 | MSTestテスト検出時 |
| BR-144-04 | 構文のみチェック | セマンティック解析を行わず属性名のみで判定 | パフォーマンス確保 |

### 計算ロジック

- 完全修飾名マッチング時、ネストクラスの区切り文字`+`を`.`に変換して比較
- パラメータ付きテスト名は`(`以降を除去して比較

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

### 操作別データベース影響一覧

データベース操作は行わない。

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR-144-01 | 解析エラー | 構文木取得失敗 | 空配列を返却 |
| ERR-144-02 | 無効な範囲 | 指定範囲がドキュメント外 | 空配列を返却 |

### リトライ仕様

リトライは行わない。

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

トランザクション管理は不要（読み取り専用処理）。

## パフォーマンス要件

- CodeLens表示のためリアルタイム処理が必要
- 構文のみのチェックで高速処理を実現
- 大規模テストファイルでも100ms以内に完了

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

- ユーザーコードの読み取りのみを行う
- テスト実行自体は行わない

## 備考

- 継承関係によるテストメソッド検出は行わない（設計上の制限）
- 新しいテストフレームワークはITestFrameworkMetadata実装で追加可能

---

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

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

### 推奨読解順序

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

テストフレームワークメタデータの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ITestFrameworkMetadata.cs | `src/Features/Core/Portable/Testing/TestFrameworks/ITestFrameworkMetadata.cs` | テストフレームワークメタデータのインターフェース（7-13行目） |
| 1-2 | XUnitTestFrameworkMetadata.cs | `src/Features/Core/Portable/Testing/TestFrameworks/XUnitTestFrameworkMetadata.cs` | xUnit属性の定義（11-24行目） |
| 1-3 | NUnitTestFrameworkMetadata.cs | `src/Features/Core/Portable/Testing/TestFrameworks/NUnitTestFrameworkMetadata.cs` | NUnit属性の定義 |
| 1-4 | MSTestTestFrameworkMetadata.cs | `src/Features/Core/Portable/Testing/TestFrameworks/MSTestTestFrameworkMetadata.cs` | MSTest属性の定義 |

**読解のコツ**: `ITestFrameworkMetadata`は単一メソッド`MatchesAttributeSyntacticName`を持つシンプルなインターフェース。各実装は属性名の文字列マッチングを行う。

#### Step 2: サービスインターフェースを理解する

テストメソッド検索サービスの契約を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ITestMethodFinder.cs | `src/Features/Core/Portable/Testing/ITestMethodFinder.cs` | メソッド検索インターフェース（13-31行目） |

**主要処理フロー**:
1. **18-19行目**: `GetPotentialTestMethodsAsync`で範囲内のテストメソッドを検索
2. **24-25行目**: `IsTestMethod`でノードがテストメソッドか判定
3. **30行目**: `IsMatch`で完全修飾名とのマッチング

#### Step 3: 抽象実装を理解する

テストメソッド検索の具体的な実装を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AbstractTestMethodFinder.cs | `src/Features/Core/Portable/Testing/AbstractTestMethodFinder.cs` | 抽象基底クラス（17-113行目） |

**主要処理フロー**:
- **23-25行目**: 完全修飾名表示フォーマットの定義
- **33-48行目**: `GetPotentialTestMethodsAsync`の実装（範囲交差チェック）
- **50-79行目**: `IsMatch`の実装（名前正規化と比較）
- **81-84行目**: `IsTestMethod`の実装（抽象メソッド呼び出し）
- **86-112行目**: `GetPotentialTestNodesAsync`の実装（ノード走査）

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

```
ITestMethodFinder (インターフェース)
    │
    └─ AbstractTestMethodFinder<TMethodDeclaration> (抽象基底)
           │
           ├─ TestFrameworkMetadata (ITestFrameworkMetadata[])
           │      │
           │      ├─ XUnitTestFrameworkMetadata
           │      ├─ NUnitTestFrameworkMetadata
           │      └─ MSTestTestFrameworkMetadata
           │
           ├─ GetPotentialTestMethodsAsync()
           │      └─ GetPotentialTestNodesAsync()
           │             └─ IsTestMethod() (abstract)
           │
           ├─ IsTestMethod()
           │      └─ MatchesAttributeSyntacticName()
           │
           └─ IsMatch()
                  └─ ToDisplayString() → 完全修飾名比較
```

### データフロー図

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

ドキュメント ───────▶ GetSyntaxRootAsync ───────▶ 構文木
    +                      │
テキスト範囲               ▼
                    DescendantNodesAndSelf
                           │
                           ▼
                    メソッド宣言ノード
                           │
                           ▼
                    IsTestMethod()
                           │
                    ┌──────┴──────┐
                    ▼              ▼
            テスト属性あり   テスト属性なし
                    │              │
                    ▼              ▼
            結果に追加        スキップ
                    │
                    ▼
            テストメソッド配列

完全修飾テスト名 ───────▶ IsMatch() ───────▶ bool
                           │
                           ▼
                    名前正規化
                           │
                           ▼
                    文字列比較
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ITestMethodFinder.cs | `src/Features/Core/Portable/Testing/` | インターフェース | テストメソッド検索の契約 |
| AbstractTestMethodFinder.cs | `src/Features/Core/Portable/Testing/` | ソース | 抽象基底クラス |
| ITestFrameworkMetadata.cs | `src/Features/Core/Portable/Testing/TestFrameworks/` | インターフェース | フレームワークメタデータ契約 |
| XUnitTestFrameworkMetadata.cs | `src/Features/Core/Portable/Testing/TestFrameworks/` | ソース | xUnit属性定義 |
| NUnitTestFrameworkMetadata.cs | `src/Features/Core/Portable/Testing/TestFrameworks/` | ソース | NUnit属性定義 |
| MSTestTestFrameworkMetadata.cs | `src/Features/Core/Portable/Testing/TestFrameworks/` | ソース | MSTest属性定義 |
