Newer
Older
TIASShot / docs / 03_PLAN / PLAN_05_テスト網羅性向上計画.md

テスト網羅性向上計画 (Test Coverage Improvement Plan)

目的 (Purpose)

人間による実機確認を「カメラ・光源 SDK の実呼び出し」と「実画像の見た目」だけに絞り,それ以外の回帰を自動テストで担保する.

方針の本体(常に従う規約)は testing.md に置き,本書はそこへ移行するための段取り(フェーズ・完了条件・リスク)を定める.

背景 (Background)

  • 2026-10-06 の /auto-audit では,報告した指摘 26 件の多くが「CameraBase・Form1・カメラ層で再現テストを書けない」ことを理由に自動修正できなかった.中でも保存失敗が成功扱いになる件や終了時の画像取りこぼしは,データ欠損に直結する.
  • 旧方針は「ハードウェア結合層は自動テスト対象外」としていた.しかし実際には,偽カメラ(SelfTest/SelfTestCamera)とヘッドレス Form1(Form1.SelfTest.cs)がすでにあり,セルフテストでは CameraBase の校正〜保存を通している.NUnit で細かく検証していないだけで,自動化できない範囲は思っていたより狭い.
  • 異常系(保存失敗・終了時・設定ファイル破損)に問題が集中していた.正常系の目視確認だけでは見つからない種類の不具合である.

現状の手動確認の内訳 (Current Manual Checks)

確認内容本当に実機が要るか移行先
カメラ接続・露光/ゲインの反映・フレーム取得要る(SDK の実呼び出し)実機に残す(層④)
光源の ON/OFF要る(シリアル通信)実機に残す(層④)
校正の自動開始〜完了,撮影ボタンの有効化判断ロジックは不要層②(偽カメラ+ヘッドレス Form1)
単発・連続撮影でファイルが保存される不要層②・セルフテスト
保存失敗・ディスク満杯・設定破損時の挙動不要(失敗を注入できる)層②
アプリを閉じてもエラーが出ない終了順序の判断は不要層②(SDK の停止そのものは層④)
校正結果・色の妥当性合成チャートでは不十分実機録画データによる回帰(層①の拡張)

目標とする 4 層モデル (Target Four-Layer Model)

層対象テスト手段
① ピュアロジック色補正・チャート検出・CSV・設定・ゲイン計算・画像統計NUnit(実値で検証)
② 結合ロジックCameraBase の校正の状態遷移・撮影ループ・SaveThread・失敗通知・終了処理,Form1 の UI 連携メソッドNUnit+偽カメラ+ヘッドレス Form1(STA スレッドでメッセージを処理するハーネス)
③ SDK アダプタIScam・Lucam・LightSource判断ロジックを純粋関数へ切り出して層①で検証する.SDK 呼び出しそのものは層④
④ 実機SDK の実呼び出し・実画像の見た目短い手動チェックリスト(TEST_01)

詳細な判断基準は testing.md を参照する.

決定事項 (Decisions)

2026-10-06 にユーザーと合意した.

項目決定
テストプロジェクトへの System.Windows.Forms 参照追加許可する(.NET Framework 標準アセンブリで NuGet 依存は増えない)
層②(CameraBase を NUnit で検証)行う
層③(SDK アダプタからの判断ロジック切り出し)撮影・保存の信頼性修正(/auto-audit 報告の束 B)と同時に行う
実機録画データ撮る.舌診チャートと白板のみ(舌の画像は個人情報のため扱わない)
カバレッジ数値目標は課さず,「一度も通っていない箇所」を見つける地図として使う
実機録画データの置き場所Git LFS で管理する.CI が無くテストは開発マシンでしか回らないため,コードと同じ版のデータが clone で確実に手元に来る方式を選んだ.1 機種・1 場面あたり 3〜5 フレームに絞り,合計 100〜150MB 程度に抑える(GitHub の LFS 無料枠はストレージ 1GB・転送量 1GB/月)
層②のテストの実行時間層②全体で 30 秒を目安とし,1 件あたり 15 秒のタイムアウトを付ける.超えそうなときはテスト用設定(校正フレーム数等)を見直して速くする./auto-audit は修正 1 件ごとにテスト一式を何度も回すため,ここが延びると全作業が遅くなる
/verify に含めるか常に含める(run_selftest.py は絞り込まずに全件実行するので追加設定は不要).CI が無く,/verify・/auto-audit が実質唯一の自動チェックのため,カテゴリで分けて通常は回さない運用にはしない
メモリ量で判定するテスト2026-10-06 に追加したリーク再現テスト等は [Category("Memory")] に分け,環境による不安定さが出たら通常の実行から外せるようにする

フェーズ (Phases)

フェーズ 0: 方針の文書化

  • 本書を作成し,testing.md を 4 層モデルに改訂する
  • 完了条件: ユーザーのレビューを経て main に取り込む

フェーズ 1: 層②の基盤と試作

  • テストプロジェクトに System.Windows.Forms の参照を追加する
  • テスト用ハーネスを作る
    • STA スレッドを立て,ヘッドレス Form1 を生成してハンドルを作る(SelfTestStart)
    • 条件が満たされるまでメッセージを処理する待機処理(タイムアウト必須).SelfTestRunner の Application.DoEvents による待機と同じ考え方で,可能なら共通化する
    • 一時フォルダと一時 config.xml を用意する(Config.Load(path) を使う)
  • テスト用の一時設定では校正フレーム数(Calib/Frames)等を小さくし,1 件あたり 1 秒前後で終わるようにする
  • 既存のメモリ量判定テストに [Category("Memory")] を付ける
  • 試作として「保存失敗が成功扱いになる」件(/auto-audit 報告台帳)の赤テストを書き,修正する
  • 完了条件:
    • ハーネスを使うテストが 3 回連続で安定して緑になる
    • 層②の各テストに 15 秒のタイムアウトが付いている
    • Release ビルドに影響しない(SELFTEST は Debug 系のみ)
  • 状態: 完了(2026-10-06)
    • ハーネスは TIASshot.Tests/IntegrationHarness.cs.一時 config の作成と待機処理は TIASshot/SelfTest/SelfTestConfig.cs・SelfTestPump.cs に切り出し,セルフテストのランナーと共用する
    • 試作テスト CameraBaseSaveIntegrationTests(保存成功・単発の保存失敗・連続撮影の途中の保存失敗)は 3 回連続で緑.保存失敗の 2 件は修正前のコードで赤になることを確認した.層② 3 件の所要時間は計約 5 秒
    • 失敗の注入は,偽カメラの派生で保存先と同名のフォルダを作り Cv2.ImWrite に false を返させる方法をとった(例外ではなく false になることを単体テストで固定している)
    • 引き続き残る課題: CalcTcc の校正画像の保存失敗は「自動校正完了」と表示される(失敗時に校正済みとするかが仕様判断のため未修正)

フェーズ 2: 層②の拡充

  • 次の観点を網羅する.各観点に失敗を注入するケースを 1 つ以上含める
    • 校正の状態遷移(チャート検出 → 固定判定 → 変換行列算出 → 撮影ボタン有効化)
    • 撮影ループ(単発・連続・枚数 0・間隔 0)
    • SaveThread(保存失敗・例外時の後始末・残りフレームの破棄)
    • 切断・終了の順序(保存中の終了,校正中の終了)
    • Form1 の UI 連携メソッド(UI スレッド外からの呼び出しを含む)
  • /auto-audit 報告台帳のうち,層②で再現テストを書けるようになった項目をここで修正する
  • 完了条件: 上記の各観点に正常系と失敗注入のテストがそろい,層②全体の実行時間が 30 秒の目安に収まる

フェーズ 3: 層③の切り出し

  • 撮影・保存の信頼性修正(束 B)と同時に,IScam・Lucam・LightSource から判断ロジックを純粋関数として切り出す
    • 例: ROI とフレームサイズの照合,ホワイトバランスのゲイン算出,フレームバッファのサイズ検査,光源ポートを開けなかったときの扱い,例外を通知に変える処理
  • SDK を呼ぶ部分は「受け取って渡すだけ」の薄いアダプタに残す
  • 完了条件: 切り出した関数に層①のテストがあり,切り出し直後に実機確認を 1 回行う

フェーズ 4: 実機録画データによる回帰

  • 開始時に Git LFS を準備する(このマシンへの git lfs の導入確認,.gitattributes での対象パターン指定,GitHub 側の LFS の利用確認)
  • 人間が実機(ImagingSource・Lumenera の両方)で舌診チャートと白板を撮影し,フレームを可逆形式(PNG)で保存する.1 機種・1 場面あたり 3〜5 フレームとする
  • 録画フレームを繰り返し流して校正を通し,チャート検出のマスク位置,変換行列(基準 CSV との一致.許容誤差つき),変換後の色票の色差を自動で比較するテストを作る
  • 完了条件: 両機種の録画データで回帰テストが緑になり,データが Git LFS で管理されている

フェーズ 5: 手動チェックリストの縮小とカバレッジの確認

  • Microsoft.CodeCoverage(テストプロジェクトに導入済み)で未通過の箇所を確認し,重要な経路の抜けを埋める
  • TEST_01 の手動テストを下記の目標形に改訂する
  • 完了条件: TEST_01 の改訂が main に取り込まれる

手動確認の目標形 (Target Manual Checklist)

フェーズ 5 完了後に TEST_01 に残す項目の想定.

  • 両機種(ImagingSource・Lumenera)でカメラが自動接続され,プレビューが出る
  • 露光・ゲインの設定がプレビューに反映されている(目視)
  • 実物の舌診チャートで自動校正が完了する
  • 撮影した画像の色が目視で妥当である
  • 光源が ON/OFF する
  • 撮影中・保存中にアプリを閉じても固まらない(SDK の停止が絡むため最終確認として残す)

※ 保存ファイルの有無・内容,失敗時の通知,撮影ボタンの有効/無効といった項目は層②とセルフテストに移し,手動では確認しない.

リスクと対策 (Risks)

リスク対策
WinForms のテストがハング・不安定になる(STA・メッセージ処理の誤り)ハーネスを 1 か所に集約し,待機には必ずタイムアウトを付ける.新しいハーネス利用テストは 3 回連続実行で安定性を確認してから取り込む
テストの実行時間が延びて /verify や /auto-audit が遅くなる層②のテストに [Category("Integration")] を付けて所要時間を計測し,全体 30 秒の目安を超えそうならテスト用設定を見直して速くする(/verify から外すことはしない)
テストが Form1 の内部構造に依存して壊れやすくなるForm1.SelfTest.cs のアクセサ(SelfTestMessage・SelfTestLastError・SelfTestShotsEnabled 等)経由でのみ観測する.足りないアクセサはそこに追加する
メモリ量で判定するテストが環境によって不安定になる2026-10-06 に追加したリーク再現テスト(プライベートメモリ増分のしきい値判定,OpenCV 内部の参照カウント読み取り)を棚卸しし,必要なら [Category("Memory")] に分ける
実機録画データが大きい/個人情報を含む舌診チャートと白板に限る.フレーム数を絞り Git LFS で管理する.LFS の転送量の無料枠(1GB/月)を超えそうなら,データの削減か有料枠を検討する