Newer
Older
SmTIAS-LightSim / .claude / rules / testing.md

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

テスト方針 (Test Policy)

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

基本方針 (Basic Policy)

  • フレームワーク: pytest
  • 配置: tests/ 配下に src/sm_tias_lightsim/ のサブパッケージ構造をミラー
  • カバレッジ目標: 数値目標なし.代わりに「核となる計算ロジックは必ず単体テスト」というルールを徹底する
  • 通常実行: uv run pytest
  • 重いテストを含む実行: uv run pytest -m "" --no-strict-markers / デフォルトでスキップは -m "not slow"

テストの配置

tests/
├── conftest.py             # 共通フィクスチャ
├── fixtures/               # テストデータ(小さい STL / 既知の輝度マップ等)
├── geometry/
│   └── test_loader.py
├── scene/
│   ├── test_builder.py
│   └── test_schema.py
├── render/
│   └── test_runner.py      # 軽量シーンの end-to-end
├── test_uniformity.py      # SmTIAS-Evaluation 互換の数値検証
└── evaluation/
    ├── test_roi.py
    └── test_zones.py

ファイル・関数命名

  • ファイル: test_<対象モジュール>.py
  • 関数: test_<振る舞い> 例: test_grayscale_conversion_uses_rec709_coefficients
  • クラス(任意): Test<クラス名> で振る舞いごとにグループ化可能

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

  • 核計算ロジック: uniformity.py, evaluation/zones.py, evaluation/radial.py
    • 既知の入力(合成輝度マップ)に対して期待値を確認
    • SmTIAS-Evaluation の元実装と数値が一致することを保証
  • 入力バリデーション: scene/schema.py
    • 不正 YAML が ValidationError を投げること
    • 必須フィールド欠落・参照不整合を検出すること
  • データ変換: geometry/transforms.py(mm ↔ m 等)
    • 変換が可逆であること
  • YAML → Mitsuba scene 変換: scene/builder.py
    • 期待される scene dict を生成すること(実レンダリングはせず構造のみ確認)

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

  • CLI のエントリポイント(cli/render.py, cli/evaluate.py)
    • 統合テスト 1 本でカバー
  • 可視化(evaluation/visualize.py)
    • 図の見栄えはテストしにくい.「ファイルが生成されたか」程度の smoke テストで十分

モック方針 (Mocking)

  • Mitsuba をモックしない.小さい合成シーン(64×64 等)で実物を回す
    • 理由: モックすると物理量の妥当性検証ができなくなる.実機との比較が目的のため
  • ファイル I/O はモックしない.tmp_path フィクスチャで実ファイルを使う
  • 乱数を含むテストは必ず seed を固定する

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

レンダリングを伴うテストは @pytest.mark.slow を付けて区別:

import pytest


@pytest.mark.slow
def test_render_baseline_matches_reference():
    ...
  • 通常実行(高速): uv run pytest -m "not slow"
  • 全テスト実行(CI 等): uv run pytest

マーカー定義は pyproject.toml の [tool.pytest.ini_options] に登録済み.

/implement パイプラインでのテスト

/implement の流れ:

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

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

テスト失敗時の運用

  • ルール変更による失敗: 規約・仕様を改める根拠があれば SPEC / GUIDE を先に更新してからテストを書き直す
  • バグ起因の失敗: 修正してから再実行
  • 単に flaky なテスト: seed 固定漏れか,乱数依存の境界値.seed を見直す

参考 (References)