diff --git a/CLAUDE.md b/CLAUDE.md index 3813c9d..b2fc126 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ ## 開発進捗 -最新: PLAN_02 優先度1 完了(連続撮影クラッシュの根本原因=`_shots` のスレッドセーフ化.`BlockingCollection` で生産者-消費者パイプライン化) +最新: テスト方針(GUIDE_08)を整備(ハードウェア結合層/ピュアロジック層を分離し,後者を NUnit で自動テストする方針) ※ 本欄は**最新ステップ 1 行のみ上書き更新**.詳細な進捗履歴(動機・設計判断・失敗パターン)は [docs/PROGRESS.md](docs/PROGRESS.md) に追記する.運用ルールは GUIDE_05「進捗記録の運用ルール(CLAUDE.md / PROGRESS.md)」を参照. ## 必須ルール(コード実装時) @@ -44,7 +44,8 @@ - ファイル命名規則: docs/01_GUIDE/GUIDE_03_ファイル命名規則.md - Git 運用ルール: docs/01_GUIDE/GUIDE_04_Git運用ルール.md - エージェント運用ルール: docs/01_GUIDE/GUIDE_05_エージェント運用ルール.md -- ※ コーディング規約,テスト方針等はプロジェクト立ち上げ時に作成する(GUIDE_01 参照) +- テスト方針: docs/01_GUIDE/GUIDE_08_テスト方針.md +- ※ GUIDE_06 コーディング規約・GUIDE_07 ディレクトリ構造規則・GUIDE_09 エラーハンドリング方針は未整備(GUIDE_01 参照) ### 02_ENV(環境) diff --git "a/docs/01_GUIDE/GUIDE_08_\343\203\206\343\202\271\343\203\210\346\226\271\351\207\235.md" "b/docs/01_GUIDE/GUIDE_08_\343\203\206\343\202\271\343\203\210\346\226\271\351\207\235.md" new file mode 100644 index 0000000..07fdf35 --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_08_\343\203\206\343\202\271\343\203\210\346\226\271\351\207\235.md" @@ -0,0 +1,89 @@ +# テスト方針 (Testing Policy) + +本プロジェクトのテストの種類・粒度・対象範囲・実行タイミングを定める. +具体的な回帰テスト手順は [TEST_01_テスト仕様](../06_TEST/TEST_01_テスト仕様.md) を参照する(本書は方針,TEST_01 は具体手順という役割分担). + +## 基本方針 (Basic Policy) + +本プロジェクトは実機カメラ(Lucam / ImagingSource)・光源・ネイティブライブラリ(OpenCvSharp)に強く依存する一方で,画像処理・色補正・設定読み込み等のハードウェアに依存しない純粋ロジックも含む.この性質に合わせ,コードを 2 層に分けてテストする. + +- **ピュアロジック層**: ハードウェア・UI・スレッドに依存しない計算/変換ロジック.**自動テスト(単体テスト)で回帰を担保する**. +- **ハードウェア結合層**: カメラ SDK・`Form1`(WinForms UI)・撮影/プレビューのスレッド・コールバックに密結合した処理.**自動テストの対象外**とし,ビルドテスト+手動テスト+実機回帰テストで担保する. + +「テストできない」と「テストしていない」を混同しない.ハードウェア結合層は原理的に自動テストが困難なため対象外とするが,ピュアロジック層は自動テスト可能であり,必ずテストを書く. + +標準に則る.NUnit の慣例(AAA: Arrange-Act-Assert)に従い,テストは実装のなぞり書きではなく**仕様(期待される入出力)を基準**に書く. + +## テストの種類 (Test Types) + +| 種類 | 対象 | 自動化 | 実行タイミング | +| --- | --- | --- | --- | +| 単体テスト | ピュアロジック層 | 自動(NUnit) | コミット前・`/implement` Phase 2 | +| ビルドテスト | ソリューション全体 | 自動(MSBuild) | 全コミット前 | +| 回帰テスト | 色補正・チャート検出の出力 | 半自動(基準データ比較) | リファクタ・修正の前後 | +| 手動テスト | 起動〜撮影〜保存の一連動作 | 手動(実機) | 機能追加・修正の完了時 | + +回帰テスト・手動テストの具体手順は [TEST_01_テスト仕様](../06_TEST/TEST_01_テスト仕様.md) に記載する. + +## テスト対象の切り分け (Test Scope) + +どのクラス・処理を自動テストの対象とするかを明示する.新しいコードを追加した際は,この表に従って対象/対象外を判断する. + +### 自動テスト対象(ピュアロジック層) + +| 対象 | テスト内容の例 | +| --- | --- | +| `ColorCorrection/ColorCorrector` | 次元拡張(`ExtendMat`)・変換行列算出・色変換の入出力.既知の入力 Mat に対する出力 Mat/数値の検証 | +| `ChartDetection/ChartDetector` | 既知のチャート画像を入力したときのマスク位置・検出結果の幾何的検証 | +| `Config` | 設定 XML のパース・型変換・範囲フィルタ(例: チャネル数の `4〜17` 絞り込み) | +| `Utils/IoUtil` | CSV の読み書き往復(`SaveMatToCsv` → `LoadMatFromCsv`)で値が保たれること | +| ゲイン更新比率の計算(`GetRatio` 相当) | 入力値・目標値・更新レートに対する比率計算 | + +### 自動テスト対象外(ハードウェア結合層) + +| 対象 | 対象外の理由 | +| --- | --- | +| `Cameras/CameraBase`・`IScam`・`Lucam` のカメラ制御・撮影/プレビュー | カメラ SDK(`dll.*` / `TIS.Imaging.*`)・フレームコールバック・実機に依存 | +| 撮影/保存のスレッド連携(`RunShotLoop` / `SaveThread`) | カメラフレーム取得・`Form1` に依存.スレッド安全性は設計レビューと実機で担保 | +| `UI/Form1`・`UI/PreviewMonitor` | WinForms UI スレッド・画面描画に依存 | +| `LightSource` | 光源のシリアル通信(実機)に依存 | + +※ ハードウェア結合層に手を入れた場合は,自動テストの代わりに**設計レビュー+実機回帰**で挙動を確認する.`/implement` の Tester フェーズでは,対象がハードウェア結合層の場合,無理にモックを作らず設計レビューで判断してよい. + +## フレームワークと配置 (Framework & Layout) + +- **フレームワーク**: NUnit(`NUnit3TestAdapter` で Visual Studio / `dotnet test` から実行). +- **テストプロジェクト**: `TIASshot.Tests`(**x64 / .NET Framework 4.8**.本体と同一ターゲット). +- **ネイティブ依存**: `ColorCorrector` 等のテストは OpenCvSharp のネイティブ DLL をロードするため,テストプロジェクトも **x64 必須**かつ OpenCvSharp ランタイムを参照すること(プラットフォームを `AnyCPU` にすると Mat 演算が実行時に失敗する). +- **配置**: ソリューションルート直下にテストプロジェクトを置く. + +```text +TIASshot/ ← ソリューションルート +├── TIASshot.sln +├── TIASshot/ ← 本体プロジェクト +└── TIASshot.Tests/ ← テストプロジェクト(NUnit) + ├── ColorCorrectorTests.cs + ├── ConfigTests.cs + └── ... +``` + +- **命名**: テストクラスは `<対象クラス>Tests`,テストメソッドは「対象_条件_期待結果」が分かる名前にする(日本語名も可). +- **粒度**: 1 テストにつき 1 つの検証観点とする.1 メソッドで多数の `Assert` を詰め込まない. +- **テストデータ**: 入力画像・基準 CSV 等は `TIASshot.Tests` 配下の専用フォルダ(例: `TestData/`)に置き,テストから相対参照する. + +## モック方針 (Mocking) + +- **過剰なモックを避ける**.ピュアロジックは実値(実際の Mat・数値)で検証する. +- **静的依存の扱い**: `Config` のような静的クラスへの依存がテストの妨げになる場合,テスト容易化のための最小限のシーム(引数化・依存の注入)を導入してよい.ただし**本番の挙動は変えない**こと. +- **ハードウェア SDK はモックしない**.モックしてまでテストする価値が低く,対象外(ハードウェア結合層)とする方針と整合させる. + +## カバレッジ方針 (Coverage) + +- **数値的なカバレッジノルマは課さない**.カバレッジ率の達成自体を目的化しない. +- 代わりに,**重要な計算経路を網羅する**ことを定性的な目標とする.具体的には,色変換行列の算出・次元拡張・CSV 往復・ゲイン更新比率といった「誤ると出力が壊れる中核ロジック」にテストを行き渡らせる. + +## 既存ドキュメントとの関係 (Relation to Existing Docs) + +- 本書(GUIDE_08)は**テストの方針**を定める. +- [TEST_01_テスト仕様](../06_TEST/TEST_01_テスト仕様.md) は**回帰テスト・手動テストの具体手順**(基準データの作成・比較方法・合格条件)を定める. +- 自動テスト(単体テスト)の具体的なケースが増えた場合は,`docs/06_TEST/` に追記する(本書には方針のみ残し,個別ケースは重複させない). diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index e69cb62..6fe457e 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -27,3 +27,7 @@ - 設計判断: `ConcurrentQueue` 単体ではなく `BlockingCollection` を採用し生産者-消費者パイプライン化。`GetConsumingEnumerable`/`CompleteAdding` で `Thread.Sleep` ポーリング待機を排除。保存連番は独立カウンタで従来順序を維持。 - 堅牢化: 撮影ループを `try/finally` で包み、例外時も `CompleteAdding()` を必ず呼んで消費者(保存スレッド)の永久ブロックを防止(例外はそのまま伝播。ユーザー向けエラー表示・撮影中断は優先度3 で別途)。 - 回帰検証: 自動テスト不可(ハードウェア依存)のため、ビルド 0/0 + 実機(校正・連続撮影・複数回・連番一致)確認 + 設計レビューで担保。 + +- [x] **テスト方針(GUIDE_08)整備** (2026-06-07): 立ち上げフローの規約整備フェーズが未着手だったため、品質管理の土台としてテスト方針を策定。ハードウェア結合層(カメラ/UI/スレッド)と純粋ロジック層を分け、後者を NUnit で自動テスト、前者をビルド+手動+実機回帰で担保する方針。 + - 動機: `/implement` のテストフェーズが毎回「テスト不可」で終わっていたが、実態は純粋ロジック層(`ColorCorrector` 等)にテストプロジェクトを立てていなかっただけ、という認識のズレを是正。 + - 後段: テストプロジェクト(`TIASshot.Tests`, NUnit / x64 / .NET Framework 4.8)の立ち上げと `ColorCorrector`・`Config`・`IoUtil` 等の初期テスト作成(次ステップ)。GUIDE_06 コーディング規約・GUIDE_07 ディレクトリ構造・GUIDE_09 エラーハンドリング方針は未整備のまま。