mcpField
T
test-coverage

test-coverage

github.com/neolabhqテスト・品質1.8k634 回インストール9 週間前に更新
リポジトリ

test-coverage について

既存のテストスイートに対するカバレッジ測定の選択と解釈を支援するリファレンススキルです。構造、ミューテーション、要件、API、仕様領域のカバレッジを区別し、それぞれの限界とコストを説明します。

主な機能

  1. 01カバレッジ種別の定義と限界
  2. 02適用・省略の判断ガイド
  3. 03エコシステム別のツール参照
  4. 04しきい値と落とし穴の分析
  5. 05費用対効果の考慮

活用シーン

  1. 01テストスイートに適した指標の選択
  2. 02カバレッジレポートの慎重な解釈
  3. 03行カバレッジ以外の不足箇所の把握

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/neolabhq/context-engineering-kit --skill test-coverage

インストール後、Claude Code で/test-coverageを入力して読み込まれたか確認します。

詳細

テストカバレッジ分析

既存のテストスイートに対するテストカバレッジ分析を選択し、適用し、解釈するためのリファレンスマニュアルです。

このスキルは知識リファレンスであり、手順ではありません。テストをいつ書くべきか、どのテストタイプを設計すべきかを指示するものではありません。それは design-testing-strategy の役割です。このスキルでは、テストが存在する段階で、テストが実際に何を(そして何をテストしていないかを)最も適切に測定する機械的な指標はどれか、また、その指標を誠実に読み取る方法を説明します。

カバレッジ分析とは

テストカバレッジ分析とは、テストスイートがソフトウェア成果物を1つ以上の軸に沿ってどの程度テストしているかを事後に測定することです。これは、特定の「テスト対象」の定義について、「テストは実際に何に触れたのか」という問いに答えます。

「カバレッジ」という言葉にはさまざまな意味があります。次のいずれかを指す場合があります。

  • 構造的/コードカバレッジ — ソースコード内のどの行、ステートメント、分岐、条件、パスが実行されたかを測定します(計測によって測定)。
  • ミューテーションカバレッジ — 意図的にソースコードへ注入した障害のうち、テストスイートが検出する割合を測定します(変異させたコードに対してスイートを再実行して測定)。
  • 要件/機能カバレッジ — どの受け入れ基準、ユーザーストーリー、仕様条項に、それを検証するテストが少なくとも1つあるかを測定します(トレーサビリティによって測定)。
  • API/統合カバレッジ — どのエンドポイント、メソッド、ステータスコード、コントラクト間のやり取り、スキーマフィールドがテストされるかを測定します(リクエスト/レスポンスの検査によって測定)。
  • 仕様ドメインカバレッジ — 同値クラス、境界値、パラメーターの組み合わせ、状態遷移、エラーパスを測定します(モデルに照らしてテスト入力を分析して測定)。
カテゴリーの修正:カバレッジはテストタイプではありません

ミューテーションテスト、MC/DC、分岐カバレッジ、RTM のリンク付け、コントラクトカバレッジ、スキーマカバレッジは、既存のテストスイートに関する測定指標です。ユニットテスト、統合テスト、E2E テスト、コントラクトテスト、スモークテストのようなテストタイプではありません。

  • 「ユニットテストとミューテーションテストのどちらを書くべきですか?」という問いは、形式が不適切です。適切な問い方は、*「ユニットテスト/統合テストはすでにあります。それらに対してミューテーション分析も実行すべきでしょうか?」*です。
  • ミューテーションツールはソースの変異版を生成し、既存のスイートを再実行します。生成されるのはスコアであり、新しいテストではありません。
  • MC/DC と分岐カバレッジは、計測した既存のスイートの実行結果から算出されるレポートです。
  • RTM のリンク付けはテストメタデータ(タグ、ID)の特性であり、独立した実行ではありません。

「テスト戦略」でミューテーションテストをユニット/統合/E2E と並列に扱っているなら、その戦略は何をテストするかとテストをどう測定するかを混同しています。この2つの問いは直交しています。

非対称性の原則

カバレッジが低いことは、テストが弱いという強い証拠です。カバレッジが高いことは、テストが強いという弱い証拠です。

カバレッジは必要条件ではあっても十分条件ではありません。テストは意味のあるアサーションがなくても行を実行できます。アサーションがゼロでも、行カバレッジ100%は日常的に達成できます(thinkinglabs.io、codeintelligently.com)。カバレッジはトロフィーではなく警告装置として使ってください。カバレッジ率を目標にした時点で、それは適切な指標ではなくなります(テストに適用したグッドハートの法則。Optivem Journalを参照)。

カバレッジ分析ではないもの
  • テスト品質の指標ではありません。 アサーションがなくても行は実行できます。
  • 正しさの指標ではありません。 カバレッジが示すのはテストが実行されたことだけであり、バグがあれば失敗したことを証明するものではありません。
  • 「十分にテストされている」の同義語ではありません。 ミューテーションテストを行えば、アサーションのない100%カバレッジのテストスイートが妥当でないことは日常的に明らかになります。
  • ISO/IEC/IEEE 29119に基づくリスクベースのテスト選択の代わりにはなりません。
  • 目標ではありません。 それ自体をゴールにするのではなく、最低水準と傾向として扱ってください。

型ごとの構成

このスキルでは、すべてのカバレッジの種類を、次の6つのサブフィールドで同じ順序で記載しています。

  1. 定義 — 測定対象。
  2. 測定しないもの — 限界/見落としやすい点。
  3. 代表的なツール — エコシステム別。
  4. 使用する場合と省略する場合 — 適用可否の判断基準。
  5. 目標値/しきい値と落とし穴 — 根拠のある数値範囲(必ずリスクに関する注意書きを添えます)と、よくある指標の不正なかさ上げ。
  6. 費用対効果の ROI — 桁違いの費用と、実際に得られるシグナルの比較。

各セクションは、これらの見出しを目印に確認してください。


構造/コードカバレッジ

コンパイル済みまたはインタープリターで実行されるプログラムに計測を組み込み、テストスイートが実行した構造要素(行、文、分岐、条件、パス)を記録して測定します。

行/文カバレッジ
  • 定義。 1回以上実行されたソースコードの行(または文)の割合です。

  • 測定しないもの。 分岐の両方の方向が実行されたかどうか。アサーションで結果が検証されたかどうか。境界値がテストされたかどうか。1行に複数の文があると指標が歪みます(Metridev)。

  • 代表的なツール。

    エコシステムツール
    JS/TSIstanbul / nyc(Jest、Vitest、Karma に組み込み済み);--coverage フラグ
    PythonCoverage.py + pytest-cov;分岐モードに対応
    JVMJaCoCo — バイトコード計測を行う業界標準
    C/C++gcov / lcov / gcovr、llvm-cov
    Gogo test -cover、go tool cover(build-cover は Go 1.20 で統合テストモードを追加)
    .NETCoverlet(オープンソースの標準)、JetBrains dotCover、AltCover。OpenCover はメンテナンスモードです — Coverlet / dotCover / AltCover を推奨します(NDepend ガイド)
    RubySimpleCov
    Swift / Obj-CXcode に組み込み(llvm-cov バックエンド)
    Rustcargo-llvm-cov、cargo-tarpaulin
    レポート形式Cobertura XML、LCOV、Clover;集約ツール:Codecov、Coveralls、SonarQube
  • 使用する場合と省略する場合。 常に有効にします。コストはほぼゼロです(CI のフラグ)。品質目標そのものとして使うことは決して避けてください。

  • 目標値/しきい値と落とし穴。 一般用途のコードでは、70~85%が一般的です(Qt ブログ)。リスクに関する注意書きを踏まえた場合に限り適用してください(下記の「リスクベースの解釈」を参照)。アサーションのないテストでも、実行した行はカバレッジに含まれます。1行に書かれた if (x) doA(); else doB(); は、片方の分岐しか実行していなくても文カバレッジが100%になります。スナップショットのみのテストは、動作を検証せずに数値をかさ上げします。

  • 費用対効果の ROI。 非常に高い — コストはほぼゼロで、テストの実行範囲におけるリグレッションを検知する警報として役立ちます。

分岐/判定カバレッジ
  • 定義。 実行された判定分岐(if、while、for、?:、switch のケースにおける true/false の結果)の割合です。
  • 測定しないこと。 複合条件の独立性(A && B が true になっても、A=true, B=false がテストされていない場合があります)。評価順序。ループの反復回数。アサーションの強さ。
  • 一般的なツール。 行カバレッジと同じです。--branch(coverage.py)で有効にします。Istanbul はブランチモード(デフォルトで分岐を考慮)を使用し、JaCoCo は分岐をネイティブにレポートします。行/ステートメントカバレッジより厳密に強力です(Graph AI)。
  • 使用する場合/見送る場合。 複雑なロジックにはデフォルトで使用します。主要な構造メトリクスには、行カバレッジより分岐カバレッジを優先してください。
  • 目標/しきい値と注意点。 ビジネスアプリでは、分岐カバレッジ70~80%が「十分に立派な」目標です(Lead With Skills)。ただし、常にリスクに関する注意事項と併記してください。複合条件は抜けを隠します。if (A || B) は、true と評価される部分条件が1つだけで、分岐全体としてfalseのケースが1つだけでも、分岐カバレッジ100%を達成します。
  • 費用対効果(ROI)。 高い — 汎用コードに最適な単一の構造メトリクスです(LinearB)。
条件カバレッジ
  • 定義。 すべての判定に含まれる各ブール値の部分条件が、少なくとも1回ずつ true と false の両方になっていることです。

  • 測定しないこと。 各部分条件が独立して結果に影響するかどうか(これは MC/DC です)。すべての組み合わせは必要ありません。

  • 一般的なツール。 分岐カバレッジと同じツールチェーンです。多くのツールでは、条件カバレッジを別の列としてレポートします。

    エコシステムツール
    JVMJaCoCo(分岐レポート内の条件カウンター)
    C / C++gcov/gcovr(--branch-counts)、Qt Coco
    .NETCoverlet(Cobertura 出力による条件カバレッジ)
  • 使用する場合/見送る場合。 複合式を含むコードでは有益ですが、単独で CI のゲートとして使う価値はほとんどありません。

  • 目標/しきい値と注意点。 すべての組み合わせを実行しなくても達成できます。if (A && B) は、{A=T,B=F} と {A=F,B=T} で条件カバレッジ100%になりますが、どちらも判定を true にしません。ゲートではなく、診断として扱ってください。

  • ROI: 中程度 — 分岐カバレッジが高いのにバグが残る「理由」を調べる際の診断には有用ですが、ゲートには適しません。

MC/DC — 修正条件/判定カバレッジ
  • 定義(Wikipediaより):

    1. すべての入口/出口ポイントを少なくとも1回呼び出します。
    2. すべての判定で、各結果を少なくとも1回得ます。
    3. 判定内のすべての条件で、各結果を少なくとも1回得ます。
    4. ほかの条件を固定したまま、各条件が判定結果に独立して影響することを示します。

    n 個の条件の場合、独立性ペアを使えば、網羅的な複数条件カバレッジの 2^n 件よりはるかに少ない n+1~2n 件のテストで MC/DC を達成できます(LDRA)。

  • 測定しないもの。 ループの反復回数、データ値、統合パス、アサーションの強さです。

  • 代表的なツール。 LDRA TBvision、Rapita RapiCover、VectorCAST、Razorcat TESSY、Qt Coco、Parasoft C/C++testです。ほとんどが商用で、オープンソースの MC/DC はまれです。

  • 使う場合/使わない場合。 規格で義務付けられている場合(DO-178C DAL A、ISO 26262 ASIL D、IEC 62304 Class C の高リスクモジュール、EN 50128 SIL 4、IEC 61508 SIL 4)に使用します。規制対象外の分野では、ブランチカバレッジとミューテーションテストで同じ目的をより低コストで達成できます。

  • 目標/しきい値と落とし穴。 規制対象の分野では、定義上100%です。C系言語の短絡評価により、一部の独立性ペアが到達不能になることがあります。また、コンパイラー最適化によって条件が統合される場合があるため、カバレッジ計測用ビルドでは最適化を無効にする必要があります。つまり、カバレッジ計測用バイナリーとリリース用バイナリーが異なり、これは規制上のリスクとして認識されています(Verifysoft)。

  • 費用対効果(ROI)。 コストは非常に高く(専門的なツールチェーン、作業、文書化の負担)、法律や規格で要求される場合にのみ高い価値があります。

関数/メソッドカバレッジ
  • 定義。 宣言された関数/メソッドのうち、少なくとも1回呼び出されたものの割合です。

  • 測定しないもの。 関数本体に関することは何も測定しません。

  • 代表的なツール。 ほとんどの構造カバレッジツールが、補助列として報告します。

    エコシステムツール
    JVMJaCoCo(メソッドカウンター)
    .NETCoverlet(methods 列)
    Pythoncoverage.py(report -m の粒度)、pytest-cov
    JS/TSIstanbul(lcov/json-summary の functions 指標)
  • 使う場合/使わない場合。 「モジュールを見落としていないか」を手早く確認する用途に使います。主要な指標として使ってはいけません。

  • 目標/しきい値と落とし穴。 エラーパスが内部でカバーされていなくても、正常系テストで多くの関数が呼び出されるため、しばしば実態以上に高い値になります。

  • ROI: 低く、情報提供に限られます。「モジュールを見落としていないか」を検知するトリップワイヤーとしては有用ですが、ゲートには適しません。

パスカバレッジ
  • 定義。 関数内を通る、線形独立な一意のパスの割合です。サイクロマティック複雑度 V(G) = decisions + 1 によって上限が定まります(サイクロマティック複雑度)。

  • 測定しないもの。 単純でない関数では実用的なものを何も測定しません。N 個の判定があればパス数は 2^N になり、ループがある場合は無制限です。

  • 代表的なツール。 一部の商用のセーフティクリティカル向けツールが基底パス数を報告しますが、CI の成果物として使われることはまれです。

    エコシステムツール
    セーフティクリティカルな C/C++LDRA TBvision、VectorCAST(基底パス指標)
    任意/複雑度の代替指標lizard、radon、SonarQube(サイクロマティック複雑度をパス指標ではなく上限として使用)
  • 使う場合/使わない場合。 カバレッジ目標として使われることはまれです。サイクロマティック複雑度は、異なるフローを実行するために必要なテスト数の最小値を示す複雑度のシグナルとして、より有用です。

  • 目標/しきい値と落とし穴。 組み合わせの爆発が起こります。ほとんどの本番コードはパスカバレッジのレベルでは未カバーですが、それで問題ありません。

  • ROI: 本番コードでは低く、ごく小さく非常に高いクリティカリティを持つ関数でのみ意味があります。それ以外では複雑度をシグナルとして使い、それ以上は追求しません。


カバレッジ分析としてのミューテーションテスト

リマインダー: ミューテーションテストは、既存のテストスイートに対するカバレッジ分析です。テストの種類ではありません。 スコアと生き残ったミュータントの一覧を生成しますが、新しいテストは生成しません。単体テスト/統合テストのスイートの代わりに使うのではなく、これらのスイートに対して適用します。

定義

ミューテーションテストでは、ソースコードに小さな構文上の変更(「ミュータント」)を加え、各ミュータントに対して既存のテストスイートを再実行します。特定のミュータントに対して少なくとも1つのテストが失敗した場合、そのミュータントはキルされたことになります(スイートがその欠陥を検出しました)。すべてのテストが成功した場合、そのミュータントは生き残ったことになります(スイートはその変更を検出できません)。これはソースコードの到達範囲ではなく、テストスイートの欠陥検出能力を測定します(Stryker のドキュメント)。

一般的なミューテーション演算子:

  • 算術演算子 — + → -、* → /、++ → --。
  • 条件/関係演算子 — < → <=、== → !=、&& → ||。
  • ブール値/否定 — true → false、! を削除。
  • 文の削除/ブロックの削除。
  • 戻り値 — return x → return null / return ""。
  • リテラル定数のインクリメント/デクリメント。
  • 条件境界 — > → >=。
ミュータントの状態(Stryker のドキュメント)
状態意味
Killedミュータントに対して少なくとも1つのテストが失敗しました。スイートが欠陥を検出しました。
Survivedミュータントに対してすべてのテストが成功しました。スイートは検出できません。
No coverage変更されたコードを実行したテストがありません(別個のギャップ — そのコード自体がテストされていません)。
Timeoutテストが停止しました。通常はキルとしてカウントされます(スイートは異常な動作を実際に検出しました)。
Compile error / runtime errorミュータントが構文上/意味上無効です。通常は除外されます。
Ignored設定によって除外されました(生成コード、グルーコードなど)。

スコア:mutation_score = killed_mutants / (total_mutants - equivalent_mutants - errors)。ツールによっては、カバレッジ対象のミュータントのみを基準とした「killed%」も報告します。

測定しないもの
  • デッドコード領域 — no coverage として表示され、「行がカバーされていない」場合と同じです。
  • アサーションの意味的な正しさ — 間違っていても厳格なアサーションであれば、ミュータントをキルします。
  • 境界値データ — 演算子ミュータントはこれを近似しますが、BVA に取って代わるものではありません。
  • 同等のミュータント — 観測可能な動作が同一になるバリエーションです。一般に検出は決定不能であり、確実な方法は手動レビューのみです。最新のツール(Stryker TypeScript Checker、Major を備えた PIT)は、ヒューリスティックによってこうしたミュータントを減らします。ミューテーションスコア 100% を目指さないでください — 同等のミュータントがあるため、漸近的に達成不可能です(Stryker のドキュメント)。
代表的なツール
エコシステムツール
JS / TSStryker (StrykerJS) — TypeScript checker プラグインがコンパイルエラーとなるミュータントを除外します
.NET (C#)Stryker .NET。Microsoft Learn にドキュメントがあります
Java / JVMPIT (Pitest) — JVM の標準的なリファレンス。研究用途には Major Mutator
Pythonmutmut、Cosmic Ray、MutPy
Gogo-mutesting、ooze
PHPInfection
Rubymutant
Rustcargo-mutants
C / C++Mull — LLVM ベース
ScalaStryker4s
使用する場合と見送る場合

適用する場合:

  • スイートがすでに構造的に成熟している場合(通常、ブランチカバレッジが80%超)。テストスイートがまばらな状態では、ミューテーションの結果は no coverage が大半を占め、構造的カバレッジから分かる以上の新たな知見は得られません。
  • 成果物が純粋なロジックの中核部分である場合 — 金融計算、セキュリティ上重要な検証、パーサー、暗号化、認可判断など。
  • 重要度が十分に高く、テストスイートの見落としが重大なリスクにつながる場合。

見送る場合:

  • グルーコード、コントローラー、フレームワークの配線 — 宣言的な構造に対するオペレーターはノイズを生みます。
  • UI のレンダリング — 同等のものが大半を占めます。
  • 設定、DTO、宣言的なシリアル化。
  • まだ構築中の新しいテストスイート。
  • N×スイートの実行時間が許容できないほど長くなる、CI のフィードバックループが短い場合(カバレッジを諦めるのではなく、増分分析で軽減してください)。
目標値/しきい値と落とし穴

Stryker のデフォルト値(設定):high: 80、low: 60、break: null。しきい値を下回るとビルドが失敗するよう、break を設定します。リスクに留意して適用してください。純粋なロジックの中核部分を対象とした成熟したユニットテストスイートでは、60~80% が妥当な開始点です。グルーコードには決して適用しないでください。よくある落とし穴:同等なミュータントを追いかける(漸近状態になる)、UI/設定に実行する(ノイズが生じる)、浅いテストスイートに実行する(カバレッジですでに示されていることを再報告する)。

費用対効果
  • コスト。 CPU 負荷は二次関数的に増加する傾向があります。60秒のテストスイートで1,000個のミュータントが生成される場合、最適化なしでは最大で1,000 × 60秒かかります。最新のツールでは、増分分析、ミュータントごとのテスト選択、並列ランナーによって負荷を軽減します。
  • メリット。 構造的カバレッジでは検出できないアサーションの不足や過剰なモック化を検出します。アサーションの強さをスコア化できる唯一の実用的なカバレッジ手法です — 「アサーションなしでカバレッジ100%」という主な失敗パターンを検出します(codeintelligently.com)。
  • CI のパターン。 PR の差分に対して増分ミューテーションを実行し、重要なモジュールについては夜間に全体実行します(oneuptime、またgreg4cr.github.ioの研究まとめも参照)。
構造的カバレッジとの関係

ミューテーションテストは構造的カバレッジを包含し、補完します。

  • 到達不能なコード内のミュータントは no coverage となります — 「行がカバーされていない」と同じシグナルです。
  • カバーされているコード内で生き残ったミュータント — 「カバーされているが、意味のある検証がされていない」状態 — は、構造的カバレッジでは見えません。

要件/機能カバレッジ

定義

仕様の成果物(要件、ユーザーストーリー、受け入れ基準、規制条項)と、それを検証するテストとの対応付けです。

requirements_coverage = requirements_with_>=1_passing_test / total_requirements

基盤となる成果物は**要件トレーサビリティマトリクス(RTM)**です。要件とテストケースを対応させる二次元の表です(ISTQB 用語集)。次のことが可能になります。

  • 前方トレーサビリティ — すべての要件にテストがありますか?
  • 後方トレーサビリティ — すべてのテストが要件にたどり着きますか?
  • 変更影響分析 — 要件 X が変更されたとき、どのテストを見直す必要がありますか?
測定できないこと
  • テストが正しいかどうか — 誤ったアサーションに対するテストが成功しても、RTM の項目はチェック済みになります。
  • 要件自体が完全かどうか — 要件セットにシナリオが欠けていれば、RTM のカバレッジが100%でも意味はありません。
  • コード到達度 — RTM は構造的カバレッジとは独立しています。
代表的なツール
ツール種別備考
Jira + Xray / Zephyr / Test ManagerALMストーリー ↔ テストをチケット内でリンク
Polarion、IBM DOORS / DOORS Next、Codebeamer規制ドメイン向け ALMDO-178C / ISO 26262 における Tier 1
スプレッドシート + テスト名内のタグ軽量小規模チームでは機能するが、規模が大きくなると破綻する
BDD シナリオレポートBDD 準拠Cucumber + Pickles レポートジェネレーター
@Tag("AC-123") 形式のアノテーションコードレベルJUnit / pytest のタグベースで AC ID にリンク

BDD エコシステムでは、Gherkin の Scenario: ブロックが受け入れカバレッジの単位です。各 AC は理想的には 1 つ以上のシナリオにマッピングされます(BDD の基本原則: 1 シナリオ、1 振る舞い — Automation Panda)。ツール: Cucumber(マルチ言語)、SpecFlow(注: 現在活発なコミュニティフォークは Reqnroll)、behave(Python)、pytest-bdd、Robot Framework、Behat(PHP)。

基礎となる標準: ISTQB Foundation Level は、RTM を体系的なテスト設計の基礎成果物として扱っています。ISO/IEC/IEEE 29119 のパート 1〜5 は、テスト計画、テスト設計、テスト実行の各レベルでのトレーサビリティを要求しています(ISTQB と 29119 のマッピングは rcolomo.com にあります)。規制上のトレーサビリティは、DO-178C、ISO 26262 パート 6 のワークプロダクト、IEC 62304 の検証記録、FDA 21 CFR Part 820 において必須です。

いつ使うか、いつ省略するか
  • 使う: 明示的な受け入れ基準があるもの、規制対象ソフトウェア、契約上の成果物。テスト名に AC ID を埋め込む場合(it("AC-3: rejects mismatched passwords"))は低コストです。
  • 省略する: 使い捨てのスクリプトや、要件が文書化されていない社内専用ツール。
目標 / しきい値と落とし穴

100% の要件カバレッジは妥当な目標です — 文書化されたすべての AC に少なくとも 1 つのテストがあるべきです。落とし穴は定性的なものであり、数値的なものではありません:

  • 儀式の税 — 手動更新を要求する重量級の RTM ツールは、ビットロットで朽ち果てます。
  • AC ごとに 1 テストの罠 — AC に複数の同値分割や境界がある場合、単一のテストではその AC を「カバー」したことにはなりません。
  • 願望的な要件 — 「テスト合格数」ではなく「テスト予定数」を数えると、偽のグリーンな RTM が生まれます。
  • サイレントな無効化 — リンクの整合性が強制されない限り、要件の変更はトレーサビリティを破壊します。
費用対効果 ROI
  • 高い: 必須となる規制 / 契約業務。
  • 中程度: テスト名に AC タグを付けた BDD を採用しているプロダクトチーム — コストはほぼゼロで、トレーサビリティは CI の成果物となります。
  • 低い: 個人 / プロトタイプ作業。

API / 統合カバレッジ

API カバレッジは、コードカバレッジとは独立に、テストスイートによって実行された統合面 — エンドポイント、メソッド、ステータスコード、ペイロードフィールド、サービス間コントラクト — を測定します。

エンドポイントカバレッジ
  • 定義。 (unique_endpoint_method_pairs_hit) / (total_documented_endpoint_method_pairs)。多くの場合、(endpoint, method, status_code) の組み合わせに分けて集計します。
  • 測定しないもの。 レスポンスが正しいかどうかではなく、エンドポイントにアクセスしたかどうかのみです。各ステータスコードに至る組み合わせ入力も対象外です。
  • 代表的なツール。 Schemathesis(OpenAPI/GraphQL に基づくテストジェネレーター。エンドポイントとステータスコードのカバレッジを報告します)、Dredd(HTTP API を API Blueprint/OpenAPI に照らして検証します)、カバレッジダッシュボードに取り込んだ API ゲートウェイのアクセスログ(Kong、Apigee、AWS API Gateway)、テスト実行中に観測した (method, path_template, status) の組み合わせを OpenAPI 仕様と比較して追跡するカスタムミドルウェア。
  • 使用する場合/見送る場合。 OpenAPI/GraphQL の仕様がある場合は使用します。ネットワークインターフェースのない内部ライブラリでは見送ります。
  • 目標値/しきい値と注意点。 パステンプレートの正規化(/users/123 と /users/:id)は、カスタムコレクターでよく発生する不具合です。リスクが最も高い可能性のある未文書化のエンドポイントが、カバレッジ 0%と表示されることがあります。5xx エラーの経路はテストされることがほとんどありません。
  • 費用対効果。 高いです。Schemathesis のような自動生成は低コストで、すばやく不足箇所を見つけられます。
コントラクトカバレッジ(コンシューマー駆動コントラクト)
  • 定義。 プロバイダーが検証した、コンシューマー側のインタラクション(リクエスト/レスポンスの例)の割合です。コンシューマーが特定のインタラクションを記録した Pact ファイル(JSON コントラクト)を生成し、プロバイダーは CI でそれらのコントラクトに対する検証スイートを実行します。
  • 測定しないもの。 コンシューマーが一度も送信しない入力に対するプロバイダーの動作(未検証の範囲)です。パフォーマンス、セキュリティ、スキーマの完全性も対象外です。
  • 代表的なツール。 Pact(複数言語に対応)、保存と検証レポート作成のための Pact Broker/Pactflow。Spring Cloud Contract(Groovy/YAML/Java DSL コントラクト。プロバイダー向けの JUnit/Spock テストとコンシューマー向けの WireMock スタブを自動生成し、CDC とプロデューサー駆動コントラクトに対応します)。
  • 使用する場合/見送る場合。 デプロイのサイクルがそれぞれ異なる複数の独立したコンシューマーがある場合(マイクロサービス、バックエンドを共有するモバイルアプリと Web アプリなど)に使用します。プロバイダーと一緒にデプロイされる単一コンシューマー向け API や、ライブラリ API では見送ります。
  • 目標値/しきい値と注意点。 「スキーマが有効」は「コントラクトが守られている」よりも弱い保証です。スキーマは合法なデータ形式を示しますが、コントラクトはコンシューマーが実際に依存しているフィールドと動作を示します(Speakeasy:Pact と OpenAPI の比較)。
  • 費用対効果。 複数のコンシューマーがあるアーキテクチャでは高いですが、単一コンシューマーの環境では過剰な投資になります。
スキーマカバレッジ(OpenAPI/JSON Schema/GraphQL)
  • 定義。 テストスイート全体で実行されたスキーマフィールド、列挙値、oneOf/anyOf のバリエーションの割合です。
  • 測定しないもの。 フィールドの意味上の正しさ(値が間違っていても、形状は正しい場合があります)。
  • 一般的なツール。 Schemathesis(OpenAPI からプロパティベースのテストを生成し、スキーマ要素のカバレッジ指標を出力)、フィールド単位の計測にフックを使用する Dredd、Specmatic(スキーマファーストで、コンシューマー主導およびプロバイダー主導のコントラクトに対応)、Pactflow Bi-Directional Contract Testing(ガバナンスとインタラクションの安全性のために Pact と OpenAPI を組み合わせます)。
  • 使用する場合と省略する場合。 API がスキーマで記述されている場合は常に使用してください。スキーマが信頼できない、または古い場合は省略し、まずスキーマを修正してください。
  • 目標/しきい値と落とし穴。 オプションのフィールドは見落とされやすく、null 許容性や oneOf のバリエーションはよく盲点になります。非推奨のフィールドも未カバーのまま残りがちです。
  • 費用対効果。 中程度です。プロパティベース生成と組み合わせると、最も有益です。
統合パスカバレッジ
  • 定義。 サービス間またはコンポーネント間のどの接続経路が、エンドツーエンドで実行されたかを示します。
  • 測定しないもの。 各サービス内のコードカバレッジ、部分障害条件下での動作。
  • 一般的なツール。 test_suite_id をタグ付けしてテスト実行にスパンを関連付ける分散トレーシング(OpenTelemetry、Jaeger、Tempo、Lightstep)、サービスメッシュのテレメトリ(Istio、Linkerd)。
  • 使用する場合と省略する場合。 トレーシングがすでに導入されている成熟したマイクロサービスアーキテクチャで、特に本番前環境/ステージング環境を対象とする場合に使用してください。トレーシング基盤がない場合は省略してください(カバレッジ指標だけでは、その導入コストを正当化できません)。
  • 目標/しきい値と落とし穴。 古い実行のトレースが現在の不足を覆い隠すこと、サンプリング率によって頻度の低い経路が除外されること、帯域外のバックグラウンド処理に test_suite_id タグがないことに注意してください。
  • 費用対効果。 成熟したプラットフォームでは有益性が高い一方、新規開発のプロジェクトでは導入コストが過大です。

その他のカバレッジの種類

データ/同値クラスカバレッジ
  • 定義。 コードではなく、入力の分割に基づいて測定するカバレッジです。ISTQB Foundation Level のブラックボックス技法における同値分割(EP)と境界値分析(BVA)の各項目をカバレッジ要素とします(ISTQB BVA white paper)。例:orderTotal を扱う関数で、分割が {<0, 0-99, 100-499, ≥500} の場合、EP の項目は 4 つです。さらに、0、100、500 の境界値トリプル (B-1, B, B+1) が、境界の項目として 9 つあります。
  • 測定しないもの。 コード到達性、複数パラメーターの相互作用。
  • 一般的なツール。 ツールではなく、テスト計画のチェックリストとして追跡します。一部の ALM ツールは分割へのタグ付けに対応しています。
  • 使用する場合と省略する場合。 パーサー/バリデーター/計算機のようなコードでは有益性が高くなります。単純なパススルーコードでは省略してください。
  • 目標/しきい値と落とし穴。 すべての EP とすべての (B-1, B, B+1) トリプルを対象にしてください。落とし穴:BVA のテストを 1 つ実施しただけで、分割全体を「カバーした」と数えること。
  • 費用対効果。 入力範囲が限定された純粋なロジックのコードでは、高くなります。
ペアワイズ/組み合わせ網羅率
  • 定義。 **ペアワイズ(全ペア)**テストでは、パラメーター値のすべてのペアが少なくとも1つのテストケースに現れる必要があります。複数のパラメーターが関わる不具合の多くは、2要素間の相互作用のレベルで発生します(Wikipedia)。t-way 網羅率は、3要素、4要素などへ一般化したものです。
  • 測定できないもの。 3要素以上の相互作用(t=3 に引き上げない場合)、ワークフローにおける順序の影響。
  • 代表的なツール。 Microsoft PICT(Pairwise Independent Combinatorial Tool。制約、重み付け、シードに対応)、AllPairs(Satisfice)、NIST ACTS(t は最大6まで対応)、CATS、Jenny、Hexawise。
  • 使用する場合/省略する場合。 有限の値域を持つパラメーターが4つ以上ある場合(設定マトリックス、機能フラグ、ブラウザー × OS × ロケールなど)に使用します。パラメーター数が2~3の場合は省略します(すべてを明示的に列挙します)。
  • 目標値/しきい値と落とし穴。 「ペアワイズ網羅率100%」は達成可能であり、妥当な目標です。制約の指定ミスにより、有効な組み合わせが気付かないうちに除外されることに注意してください。
  • 費用対効果。 パラメーターが4つ以上あれば非常に高くなります。総当たりでは組み合わせが爆発的に増えますが、ペアワイズではほぼ線形の範囲に収まります。
例外/エラーパス網羅率
  • 定義。 テストで実行された catch ブロック、Result.Err 分岐、if (err != nil) 分岐、および明示的なエラー返却パスの割合です。
  • 測定できないもの。 エラーが適切に処理されたかどうか(ログに記録されたか、ユーザー向けメッセージが表示されたか、再試行されたか、補償トランザクションが実行されたか)。
  • 代表的なツール。 エラー処理分岐に対するブランチ網羅率です。これを個別のメトリクスとして報告するツールはほとんどありませんが、カバレッジレポートでは通常、未実行の catch ブロックが強調表示されます。
  • 使用する場合/省略する場合。 カバレッジレポートで未実行の catch ブロックを必ず確認してください。通常、テストスイートの最大の見落としになっています。
  • 目標値/しきい値と落とし穴。 単体テストでモックを使ってエラーを注入するのは扱いにくく、最適化されたカバレッジビルドではエラーパスがデッドコードとして除去され、見えなくなることがよくあります。
  • 費用対効果。 高いです。本番環境のインシデントはエラーパスに起因することが多く、少ない監査作業で大きなリスクを低減できます。
状態/遷移網羅率
  • 定義。 テストで実行された、状態機械で宣言された遷移(および任意で禁止された遷移)の割合です。
  • スイッチレベルの網羅率: 0-switch — すべての遷移を1回ずつ実行します。1-switch — 連続する遷移のすべてのペアを実行します。2-switch — 連続する遷移のすべての3つ組を実行します。Round-trip — 状態グラフ内のすべてのサイクルを実行します(Lead With Skills)。
  • 測定できないもの。 遷移間で引き継がれるデータ、モデル化されていない動作。
  • 代表的なツール。 モデルベーステストツール — GraphWalker、ModelJUnit、fMBT。入力には PlantUML/Mermaid の状態図を使用します。
  • 使用する場合/省略する場合。 ワークフローエンジン、注文/決済のライフサイクル、UI のステップ式ウィザード、プロトコルの実装、規制対象の承認フローに使用します。ステートレスなサービスでは省略します。
  • 目標値/しきい値と落とし穴。 重要なワークフローでは、0-switch が妥当な最低ラインです。重要なパスで1-switchを実施すると、「C→A の後に A→B が機能したか?」という不具合を検出できます。禁止された遷移のテストは忘れやすいものです。
  • 費用対効果。 ワークフローソフトウェアでは高く、それ以外ではほとんどありません。

横断的なトピック

手法の組み合わせ — それぞれの手法で見つけられないもの

異なるカバレッジ軸は、それぞれ異なる種類のバグを検出します。組み合わせたときの効果は加算的ではなく、乗算的です。

具体例 — 割引コードの入力バリデーター。 if (code.length > 0 && code.startsWith("PROMO")) を考えてみましょう。"PROMO10" を使った正常系テストを1つだけ実行すると、次の結果になります。

追加する軸新たに検出できること依然として見逃すこと
行のみすべての行が1回実行されます — 行カバレッジ100%。空文字列と PROMO 以外を拒否するパスはどちらも未テストです。>= 0 へのリファクタリングがグリーンのまま出荷されます。
+ 分岐たとえば "" を使った偽分岐のテストが必要になります。これで空文字列のケースが実行されます。弱いアサーション(expect(result).toBeDefined())では依然としてバグを1つも検出できません。> を >= に変更しても、特定の拒否結果をアサートするテストがないため、スイートはグリーンのままです。
+ ミューテーション> → >= と startsWith → endsWith のミュータントを排除するには、拒否結果を具体的にアサートするテストが必要になります。code.length === MAX のような境界値は依然として未テストです。これには境界値/データカバレッジが必要です。
+ データ(BVA)MAX、MAX+1、null のケースが追加されます。code = undefined を指定してこのバリデーターを呼び出す2つ目の利用側は依然として検出できません。これにはコントラクトカバレッジが必要です。

新しい軸を追加するたびに、それ以前の軸では構造上見つけられない種類の不具合が1つ解消されます。分岐カバレッジだけでは弱いアサーションを決して検出できず、ミューテーションだけでは未テストの境界値を決して検出できず、コントラクトカバレッジだけではロジックのバグを決して検出できません。これが乗算的な効果です。以下の表に各軸とその見落としを示します。「この見落としを埋めるには、別の軸を重ねる」と読み取ってください。

軸検出できないもの
ステートメント/行未実行の分岐、アサーションの欠如、誤った戻り値
分岐/判定複合条件の独立性、ループの反復回数、アサーションの強さ
MC/DCデータ値の境界(BVA が別途必要)、アサーションの強さ
パス実行時の組み合わせ爆発。おもちゃのような関数を超えると実用的ではありません
ミューテーションデッドコード領域(カバレッジなし)、アサーションの意味的な正しさ(誤っていても厳密なアサーションならミュータントを排除できます)
RTM/要件要件が完全かどうか、テストが正しいかどうか
エンドポイント/APIフィールドレベルの形状の正しさ、動作の正しさ
コントラクト利用側が使わないプロバイダー機能という未検証部分
スキーマ意味的な正しさ、フィールドの意味
ペアワイズ3要素以上の相互作用、順序の影響
状態遷移遷移をまたいで引き継がれるデータ、モデル化されていない動作
エラーパスエラーが正しく処理されたかどうか

規制対象ではない製品コードで一般的な階層化スタックは次のとおりです。

  1. 分岐カバレッジ — CI ゲートと回帰検知用のトリップワイヤー。
  2. 要件/AC の関連付け — すべての受け入れ基準に、少なくとも1つのテストを対応させます。
  3. ミューテーションテスト — 純粋なロジックを担うコアモジュールのみ、夜間に実行します。
  4. ペアワイズ — 複数パラメーターの設定や機能の組み合わせに対して実施します。
  5. コントラクト/エンドポイントカバレッジ — 公開 API に対して実施します。
  6. 状態遷移カバレッジ — ワークフローに対して実施します。

このスタックによる CI 時間の増加はわずかで、実務上重要なテストスイートの見落としの大部分を明らかにできます。

弱いアサーションの落とし穴

高いカバレッジが品質を反映しなくなる最もよくある原因は、次のとおりです。

// 100% statement coverage. 0% useful.
it("computes discount", () => {
  discount(150);            // line executed
  // no assertion
});

もう少し巧妙な例は次のとおりです。

// 100% statement coverage. Verifies nothing semantic.
it("renders form", () => {
  expect(render(<Form />)).toMatchSnapshot();
});

どちらのテストも、触れるすべての行を実行し、カバレッジレポートはグリーンになります。どちらもミューテーションテストで検出できます。discount の演算子をどのように変更しても、アサーションが失敗しないためミュータントはすべて生き残ります。<Form /> にどのような変更を加えても、--update-snapshot でスナップショットを更新できるため変更が生き残ります。**カバレッジだけでは、これらと強固なテストスイートを見分けられません。**ミューテーションテストなら見分けられます。

対策:本番環境でバグが継続的に発生しているにもかかわらず、カバレッジレポートが80%以上を示している場合は、カバレッジ目標を引き上げる前に、問題が疑われるモジュールでミューテーション解析を実行してください。

リスクベースの解釈

カバレッジ目標は リスクに比例 させるべきです(ISO/IEC/IEEE 29119)。同じ成果物でも重要度が異なれば、同じカバレッジゲートを適用すべきではありません。以下の表を出発点として使用してください — チームのポリシー単位ではなく、成果物単位で調整してください。

重要度妥当な構造カバレッジ目標ミューテーション?RTM?MC/DC?
NONE(ドキュメント、使い捨て)—いいえいいえいいえ
LOW(内部ツール)60% 行いいえ軽量いいえ
MEDIUM(CRUD / 標準的なプロダクト)70〜80% 分岐コアロジックのみAC ごといいえ
MEDIUM-HIGH(ユーザー向けのクリティカルパス)80% 分岐コアロジック + 主要なバリデータ必須いいえ
HIGH(金銭、認証、セキュリティ)90%+ 分岐純粋なロジックのコアで必須必須 + 監査グレード標準が義務付ける場合
規制対象標準ごと純粋なロジックのコアで推奨必須 + 監査グレード標準が義務付ける場合

デルタしきい値(「X% を超えて低下してはならない」)は、一般的に絶対的な下限よりも安全です — テスト規律の後退を防ぎつつ、ゲーム的な操作に報酬を与えません(Optivem)。例外はグリーンフィールドのコードで、デルタを比較するベースラインが存在しません。

認識すべき一般的なゲーミングパターン
  1. アサーションのないテスト — 振る舞いを検証せずにコードを実行します。ミューテーションテストがこれらを明らかにします。
  2. スナップショットのみのテスト が数値を膨らませます — expect(component).toMatchSnapshot() はすべての行をカバーしますが、意味的なものは何も検証しません。1 回の不注意な --update-snapshot でスイートが無効になります。対策: スナップショットの寄与に上限を設けるか、振る舞いのアサーションを併せて要求します。
  3. デッドコードのカバレッジ — 本番では到達不能だが、リフレクション / テスト専用のエントリポイントを介してテストで実行されるコード。静的アナライザー(SonarQube、Coverity)がデッドコードを検出します。CI はデッドコードが増加したときに失敗すべきです。
  4. try/catch ラッパー で、行を実行しつつ失敗を抑制します。
  5. 1 行への凝縮 で分岐数を減らします(if (a && b) doX(); の代わりに a && b && doX()) — ツール依存のゲーミングです。
  6. 記録された理由なしにカバレッジからファイルを除外 すること。対策: コードレビューを通過する根拠を伴う // coverage:ignore コメントを要求します。
  7. 生成コードのカバレッジ が分母を膨らませます。対策: *.generated.* を確定的に除外します。
  8. RTM において 計画されたが合格していないテストをカウント すること。
  9. 1 つの些細なテストで複数の AC にタグ付け し、RTM をグリーンに見せること。
  10. 古いトレース — 古い Playwright / OpenTelemetry のトレースが現在のギャップを覆い隠します。
インストルメンテーションの注意点
  • カバレッジビルドは通常最適化を無効化するため、coverage_build_behavior ≠ release_build_behavior となります。特に C/C++/Rust と MC/DC に関連します — カバレッジビルドのバイナリはリリースビルドのバイナリではありません。
  • サンプリングベースのカバレッジでの並行テスト実行はデータを失う可能性があります。アトミックモード(Go の -covermode=atomic、JaCoCo のオフラインインストルメンテーション)を優先してください。
  • マネージドランタイム(JNI、FFI)から呼び出されるネイティブコードのカバレッジは、明示的にツールを適用しない限り通常は取得されません。
  • ホットリロード / ウォッチモードの環境は古いカバレッジデータを蓄積します。測定前に必ずクリーンアップしてください。
規制対象分野におけるカバレッジ基準
標準分野カバレッジ要件
DO-178C §6.4.4.2、Table A-7航空電子機器DAL AではMC/DCが必須、DAL Bでは判定カバレッジ、DAL Cではステートメントカバレッジ、DAL D/Eでは不要(LDRA structural coverage)
ISO 26262 Part 6 Table 9自動車ASIL DではMC/DCを強く推奨、ASIL B~Cでは分岐、ASIL Aではステートメントを最低限とする(Verifysoft)
IEC 62304医療カバレッジは安全クラスA → B → Cに応じて拡大します。監査担当者は、クラスCの高リスクモジュールにMC/DCを期待します。MISRA C/C++コーディング標準も併用するのが一般的です
MISRA C / MISRA C++組み込み(業界横断)コーディング規則への準拠が主な指標です。カバレッジは補完的なものであり、安全性が重要なコンポーネントではMC/DCが期待されます
EN 50128 / EN 50657鉄道SIL 4ではMC/DCが必須
IEC 61508機能安全の包括標準SIL 4ではMC/DC

規制対象分野では、カバレッジの目標値は標準によって定められており、ROIと照らして交渉するものではありません。選択するのは、どの標準を適用するかであり、どのしきい値を選ぶかではありません。


判断用リファレンステーブル

これらは参照用の表であり、手順ではありません。対象の成果物と重要度に一致する行を確認し、それ以外は無視してください。

重要度別のカバレッジ手法
重要度推奨されるカバレッジ指標
NONEなし — 明示的にスキップ
LOWトリップワイヤーとしての行カバレッジ。作業にACがある場合はACとの関連付け
MEDIUM分岐カバレッジ + ACとの関連付け。API成果物の場合はエンドポイントカバレッジ
MEDIUM-HIGH分岐カバレッジ + ACとの関連付け + エンドポイント/コントラクトカバレッジ。バリデーターにはミューテーションテスト
HIGH分岐カバレッジ + 純粋ロジックへのミューテーションテスト + ACとの関連付け + ワークフローの状態遷移カバレッジ + 設定のペアワイズテスト。標準で義務付けられている場合はMC/DC
規制対象(DO-178C / ISO 26262 / IEC 62304)標準の規定に従います — 通常はMC/DC + RTM + 監査可能な証拠
成果物の種類別のカバレッジ手法
成果物最も有益なカバレッジ軸
純粋なユーティリティ関数(パーサー、計算機、フォーマッター)分岐 + BVA/EP + ミューテーション
DB/キューを使用するHTTPエンドポイント分岐(ユニット) + エンドポイント + コントラクト + ステータスコード
UIコンポーネントStorybookストーリーカバレッジ + インタラクションカバレッジ + ビジュアルリグレッションのベースライン。ロジックヘルパーには分岐 + ミューテーション
ワークフローエンジン/ステートマシン状態遷移(最低0-switch、重要な経路では1-switch) + 分岐
認可/ポリシーモジュール分岐 + 規制対象の場合はMC/DC、それ以外は分岐 + ミューテーション。設計時には判定表カバレッジ
複数パラメーターの設定/フィーチャーフラグペアワイズ(PICT / ACTS) + 分岐
N個のクライアントが利用する公開APIコントラクト(Pact) + エンドポイント + スキーマ
ライブラリ/SDK分岐 + プロパティベーステスト。純粋ロジックにはミューテーションテスト。公開APIの表面カバレッジ
生成コード構造カバレッジの対象外。統合テストのみで検証
エコシステムのツールチェーン早見表
エコシステム構造変異API組み合わせBDD
JS / TSIstanbul/nyc, Vitest, JestStrykerSchemathesis, Pact JS, DreddPICTCucumber-JS, Vitest+Gherkin
Java / JVMJaCoCoPITPact JVM, Spring Cloud Contractjcunit / NIST ACTSCucumber-JVM
PythonCoverage.py + pytest-covmutmut, Cosmic RaySchemathesis, pact-pythonNIST ACTS, allpairspybehave, pytest-bdd
Gogo cover + gocover-coberturago-mutestingSchemathesis, pact-go(manual / NIST ACTS)godog
.NETCoverlet, dotCover, AltCover (OpenCover deprecated)Stryker .NETPact .NET, SpecmaticPICT, NIST ACTSReqnroll (SpecFlow のアクティブなフォーク)
RubySimpleCovmutantpact-ruby(manual)Cucumber, RSpec
C / C++gcov/lcov, llvm-covMull(vendor-specific)NIST ACTS(vendor-specific)
Rustcargo-llvm-cov, tarpaulincargo-mutants(limited)proptest combinators(limited)
PHPXdebug / PCOVInfectionpact-php(manual)Behat
UI / インタラクションカバレッジの補足

UI の比重が大きいプロジェクトでは、これらの専用カバレッジ指標が構造解析や変異解析を補完します(置き換えるものではありません)。

  • Playwright のトレースカバレッジ — Playwright はテストごとにトレース(DOM、ネットワーク、コンソール)を記録します。トレースビューアーを使うと、DOM スナップショットテストでは実現できない方法で UI カバレッジを監査可能にできます。トレース成果物によって CI のストレージ使用量が増加します。
  • Storybook カバレッジ — Storybook Test は、どのストーリー(コンポーネントの状態)にインタラクションテスト(play 関数)があるか、またはレンダリング済みスナップショットのみかを報告します。
  • ビジュアルカバレッジ — ストーリー間のピクセル差分によるリグレッション(Chromatic、Percy、Applitools、Playwright toHaveScreenshot)。カバレッジ要素は、コンポーネントの状態に対するビジュアルベースラインです。

これらは、ロジックの正しさ(その検証には分岐解析と変異解析を使用)、コンポーネント間のフロー(e2e を使用)、アクセシビリティ(axe-core / Pa11y を使用)、実機ごとの違い(BrowserStack / Sauce / デバイスファームを使用)は測定しません。


出典と参考資料

規格
構造解析と MC/DC
構造カバレッジツール
ミューテーションテスト
要件 / BDD
API / コントラクト
組み合わせ / 状態 / UI
業界の論評

コメント