---
paths: ["tests/**", "**/test_*.py", "**/conftest.py"]
---

# テスト方針 (Test Policy)

テストコード（`tests/**`・`test_*.py`・`conftest.py`）を追加・編集するときは本ルールに従うこと．

## 基本方針 (Basic Policy)

- フレームワーク: **pytest**
- 配置: `tests/` 配下に `src/tias_judge_model/` の構造をミラーする
- カバレッジ目標: **数値目標なし**．代わりに「下記の必須対象は必ず単体テストを書く」を徹底する
- **臨床データを使うテストは書かない**．テストは合成データ（小さいランダム画像と合成 manifest）のみで完結させる．手元でもサーバでも同じテストが通ること
- 実行コマンドは [ENV_04 開発コマンド](../../docs/02_ENV/ENV_04_開発コマンド.md)を参照する

## ファイル・関数命名 (Naming)

- ファイル: `test_<対象モジュール>.py`
- 関数: `test_<振る舞い>`（例: `test_split_keeps_patients_disjoint`）
- クラス（任意）: `Test<クラス名>` で振る舞いごとにグループ化してよい

## 必ずテストを書く対象 (Mandatory)

1. **患者単位分割**: 同一 `patient_id` が train / val / test に跨らないこと．**最重要**（破れると評価が無意味になる）．同じ seed で分割が再現することも確認する
2. **manifest のバリデーション**: `patient_id` 欠落・未知ラベル・重複行で停止すること（黙って除外しないこと）
3. **指標計算**: 既知の混同行列に対して macro F1・クラス別 precision / recall が期待値と一致すること．クラス ID の順序が固定されていること
4. **回収ホワイトリスト**: 画像・`manifest.csv`・個票の予測結果が回収対象に入らないこと（[SPEC_01](../../docs/04_SPEC/SPEC_01_アーキテクチャ設計.md)の制約をテストで固定する）
5. **設定スキーマ**: 不正な YAML が `ValidationError` になること．必須フィールドの欠落を検出すること

## テストを必須としない対象 (Optional)

- **CLI のエントリポイント**: 統合テスト 1 本でカバーする
- **図の生成**: 見栄えはテストしにくいため「ファイルが生成されたか」の smoke テストで十分

## モック方針 (Mocking)

- **ssh・リモート実行はモックする**．テストが実サーバに接続してはならない（転送コマンドの組み立て・回収対象の判定など，純粋なロジックを検証する）
- **ファイル I/O はモックしない**．`tmp_path` フィクスチャで実ファイルを使う
- **モデルの学習はモックしない**が，合成データ・極小モデル・1 エポックで回す（下記 slow マーカー）
- **乱数を含むテストは必ず seed を固定する**

## 重いテストの扱い (Slow Tests)

学習を回すテストは `@pytest.mark.slow` を付けて区別する．

```python
import pytest


@pytest.mark.slow
def test_train_one_epoch_on_synthetic_data():
    ...
```

- 通常実行（高速）: `uv run pytest -m "not slow"`
- 全テスト実行: `uv run pytest`

マーカーは `pyproject.toml` の `[tool.pytest.ini_options]` に登録する．

## /implement パイプラインでのテスト (Pipeline)

1. **Phase 1（実装 / coder）**: 機能実装 → 人間が動作確認
2. **Phase 2（テスト / tester）**: 本方針に従いテストを追加
3. **Phase 3（リファクタ / refactorer）**: テストを safety net として品質改善
4. **Phase 4**: ドキュメント更新

Phase 2 でテストが書きにくいと感じたら設計が悪いシグナルである．Phase 3 でモジュールを分割するか責務を見直す．

## テスト失敗時の運用 (On Failure)

- 仕様変更による失敗: 先に SPEC を更新してからテストを書き直す
- バグ起因の失敗: 修正してから再実行する
- flaky なテスト: seed 固定漏れか，学習の非決定性に依存した期待値を疑う（学習結果の数値を直接期待値にしない）

## 参考 (References)

- [pytest documentation](https://docs.pytest.org/)
