diff --git a/CLAUDE.md b/CLAUDE.md index 3813c9d..8b1424e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ ## 開発進捗 -最新: PLAN_02 優先度1 完了(連続撮影クラッシュの根本原因=`_shots` のスレッドセーフ化.`BlockingCollection` で生産者-消費者パイプライン化) +最新: 規約整備としてテスト方針(GUIDE_08)・エラーハンドリング方針(GUIDE_09)を追加 ※ 本欄は**最新ステップ 1 行のみ上書き更新**.詳細な進捗履歴(動機・設計判断・失敗パターン)は [docs/PROGRESS.md](docs/PROGRESS.md) に追記する.運用ルールは GUIDE_05「進捗記録の運用ルール(CLAUDE.md / PROGRESS.md)」を参照. ## 必須ルール(コード実装時) @@ -44,7 +44,9 @@ - ファイル命名規則: 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 +- エラーハンドリング方針: docs/01_GUIDE/GUIDE_09_エラーハンドリング方針.md +- ※ GUIDE_06 コーディング規約・GUIDE_07 ディレクトリ構造規則は未整備(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/01_GUIDE/GUIDE_09_\343\202\250\343\203\251\343\203\274\343\203\217\343\203\263\343\203\211\343\203\252\343\203\263\343\202\260\346\226\271\351\207\235.md" "b/docs/01_GUIDE/GUIDE_09_\343\202\250\343\203\251\343\203\274\343\203\217\343\203\263\343\203\211\343\203\252\343\203\263\343\202\260\346\226\271\351\207\235.md" new file mode 100644 index 0000000..36fa125 --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_09_\343\202\250\343\203\251\343\203\274\343\203\217\343\203\263\343\203\211\343\203\252\343\203\263\343\202\260\346\226\271\351\207\235.md" @@ -0,0 +1,49 @@ +# エラーハンドリング方針 (Error Handling Policy) + +本プロジェクトにおけるエラーの分類・処理方法・ログ出力の方針を定める. + +## 基本方針 (Basic Policy) + +本プロジェクトは単独開発のデスクトップ(WinForms)アプリであり,重厚なエラーコード体系や構造化ログ基盤は導入しない.既存コードの実装パターン(`ErrorMsg` + `bool` 返却・`MessageBox`・`Debug.WriteLine`・`ShowMessage`)を踏襲し,最小限に標準化する. + +- 例外を握りつぶさない.回復できないエラーはユーザーに伝えて安全に停止し,回復可能なエラーは当該処理のみ中断してアプリは継続する. +- ユーザー向けの通知(`ShowMessage` / `MessageBox`)と,開発者向けのログ(`Debug.WriteLine`)を混同しない. + +## エラーの分類 (Error Classification) + +| 分類 | 例 | 処理方針 | +| --- | --- | --- | +| 起動時の致命的エラー | 設定ファイル・参照ファイルの読み込み失敗,カメラ未接続 | 下位層で `ErrorMsg` に日本語の理由を設定し `bool` で失敗を返す.最終的に `Form` 層が `MessageBox` で通知して起動を中止する | +| 処理中の回復可能エラー | 撮影・保存・色変換中の一時的な失敗 | 例外境界で捕捉し,`ShowMessage` でユーザーに通知して当該処理のみ中断する(アプリは継続).UI 状態を適切に復帰させる | +| プログラミングエラー(バグ) | null 参照,配列範囲外,想定外の状態 | 握りつぶさない.`Debug.WriteLine` で記録し,原則そのまま伝播させて開発中に検知する | + +## エラーの処理方法 (Handling) + +### 起動時のエラー + +- `Connect()` / `Open()` 等の初期化メソッドは `bool` を返し,失敗時は `ErrorMsg` に日本語の理由を設定する. +- ユーザーへの通知は `Form` 層の `MessageBox.Show` に集約する.下位層(カメラ・光源・設定)は UI を直接呼び出さない. + +### 処理中のエラー + +- 撮影・保存・色変換など,失敗が想定される境界で例外を捕捉し,`_form.ShowMessage` で通知して当該処理を中断する. +- 中断時は UI 状態(`EnableShots` 等)を必ず復帰させる. +- スレッド同期に関わる資源は,例外時にも `finally` で確実に終端する(例: `BlockingCollection` の `CompleteAdding()` を `finally` で呼び,消費側スレッドを停止させる). + +### 共通ルール + +- 例外を握りつぶす空の `catch` を禁止する.`catch` する場合は必ず「ログ出力+ユーザー通知」または「再スロー」のいずれかを行う. +- `Mat`・`StreamWriter`・スレッド同期資源などは `using` または `try-finally` で確実に解放する. + +## ログ出力 (Logging) + +- **ログは `Debug.WriteLine` のみを使用する**.永続ログファイルは作成しない(リリースビルドでは出力されない点を許容する). +- 用途は開発・デバッグ時のトレース(パラメータ値,処理の節目,捕捉した例外の内容)とする. +- ユーザーに見せるメッセージは `ShowMessage` / `MessageBox` で行い,`Debug.WriteLine` と役割を分ける(ログ=開発者向け,メッセージ=利用者向け). + +※ 将来,撮影現場でのトラブル解析のために永続的な記録が必要になった場合は,ログファイル方式への変更を別途検討し,本方針を更新する. + +## 関連 (Related) + +- 撮影・保存処理の例外時の中断・終端は [PLAN_02_バグ修正計画](../03_PLAN/PLAN_02_バグ修正計画.md)(特に優先度3)と整合させる. +- テストとの関係は [GUIDE_08_テスト方針](GUIDE_08_テスト方針.md) を参照する(エラー処理のうち純粋ロジックで検証可能な部分は自動テストの対象とする). diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index e69cb62..476fd0f 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -27,3 +27,12 @@ - 設計判断: `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` 等の初期テスト作成(次ステップ)。 + +- [x] **エラーハンドリング方針(GUIDE_09)整備** (2026-06-07): 既存の実装パターン(`ErrorMsg`+`bool` 返却・`MessageBox`・`Debug.WriteLine`・`ShowMessage`)を土台に,エラーの分類(起動時致命/処理中の回復可能/プログラミングエラー)・処理方法・ログ方針を軽量に標準化。 + - 動機: PLAN_02 優先度3(撮影中の例外をクラッシュさせずエラー表示・中断する修正)の前に方針を確定し,場当たり実装を避けるため。 + - 設計判断: ログは `Debug.WriteLine` のみとし永続ログファイルは作らない(撮影現場での解析が必要になったら別途見直す)。空 `catch` 禁止・例外時のスレッド同期資源の `finally` 終端を明文化。 + - 残: GUIDE_06 コーディング規約・GUIDE_07 ディレクトリ構造規則は未整備のまま(既存の de-facto 確立により優先度低)。