カバレッジ 80% でパイプラインがグリーン——これは居心地の良い状態です。居心地が良すぎて、多くのチームはここで「完了」と判断してしまいます。問題は、カバレッジのパーセンテージがどのコードを実際に実行したかを示していないこと、そして最もリスクの高い部分に一度でも触れたかどうかが分からないことです。コードベースの中で最も些細な関数をほぼ完璧にカバーしながら、複雑でブランチの多いロジックがまったくテストされないままになっていても、レポートはどちらにも教えてくれません。
コードカバレッジはあらゆるテストワークフローの標準的な要素であり、テストスイートがコードベースのどれだけを実行しているかを測定するという役割は十分に果たしています。しかし、コードカバレッジはどこに集中すべきかを教えるために設計されたものではありません。この区別は一見些細なようで、実は非常に重要です。「どれだけカバーされているか」と「どの部分を本当にカバーする必要があるか」は別の問いであり、リリース前には後者こそがリリース可否を左右することがほとんどです。
カバレッジ 0% の関数が 2 つあるとします。レポート上は同じに見えます。どちらも未テスト、同等に要対応。しかし実際には同じではありません。
1 つ目が予想外の動作をする可能性は低いです。 2 つ目こそが、微妙なバグが潜む温床であり、時間的プレッシャーの下で変更を加えたときに欠陥が入り込みやすい箇所です。
カバレッジはどちらも「 0%:要対応」と見なし、どちらを先に着手すべきかの根拠をチームに与えません。
その結果、エンジニアはテストしやすいものをテストします。シンプルで取り組みやすい関数を先にテストすることでパーセンテージは上がりますが、複雑でリスクの高いコードは手つかずのまま残ります。ツールが「なぜこちらを優先すべきか」を示してくれないからです。こうしてチームは指標の最適化に走り、数値は上がっても、リスクは下がらないという状況が生まれます。
Coco 7.5 では CRAP (Change Risk Anti-Patterns) メトリクスが導入されました。これは、単体では不完全な情報しか提供できない 2 つのシグナルを組み合わせたものです。
サイクロマティック複雑度(マッケイブメトリクス)は、関数内の独立した実行パスの数を計測します。分岐のない関数の複雑度は 1 であり、 if 文・ループ・ switch ケースが追加されるたびにカウントが増加します。複雑度が高いからといって必ずバグが発生するわけではありませんが、関数の理解が難しくなり、十分なテストが困難になり、変更時に予期せぬ動作をする可能性が高まることを意味します。
テストカバレッジは、テストスイートが実際にその関数のどれだけを実行しているかを測定します。
この 2 つを組み合わせることで、関数ごとの現実のリスクを反映したスコアが算出されます。スコアが 30 を超える関数はハイリスクとしてフラグが立てられます。 このしきい値は、構造的に保守が難しく、変更時に欠陥を引き起こす可能性が高いことを示しています。
上の表は、実際のカバレッジデータから構築した Code Coverage Browser のインタラクティブな例示版です。関数はデフォルトで CRAP スコアの高い順に並んでいます。最もリスクの高い関数が赤色で上部に表示されます。
CoverageBrowser では、リスクの高い関数が色分けで表示されます。懸念すべきスコアは黄色、危険なスコアは赤色です。手動での分析や複数レポートの照合なしに、問題のある箇所を把握できます。
関数の一覧は CRAP スコアで並び替えることができ、際限のない調査作業が優先順位付けされたキューに変わります。対応が必要な関数が上位に並び、順番に処理していくことができます。ブラウザ以外のワークフローにも対応するために、 CRAP スコアは HTML および CSV レポートでも出力できます。リスクデータを CI パイプライン、スプリント計画、ステークホルダーレビューに直接組み込むことが可能です。
CRAP メトリクスはあらゆるソフトウェアチームに有益ですが、特に以下の 2 つのシナリオでその価値が際立ちます。
優先順位付けのギャップが最も痛手となるのが、大規模でレガシーなコードベースです。数年、場合によっては数十年にわたって成長してきたコードベースでは、すべての箇所で十分なカバレッジを一気に達成することは現実的ではありません。チームには、限られたテストリソースをどこに優先投入すべきかを判断するための根拠が必要です。 CRAP は、構造的なリスクとカバレッジのギャップが重なる箇所をデータに基づいてランク付けし、その意思決定を勘ではなくトレース可能な形で下せるようにします。
AI を活用したコードモダナイゼーションに関する Gartner のリサーチによると、レガシーコードに取り組む際に組織が直面する最大の課題は、マイグレーション作業そのものではなく、「知識」——既存コードが何をしているのかを理解し、変更を加える前に本当のリスクがどこにあるかを特定すること——にあります。 CRAP メトリクスはまさにそのギャップに対処するものであり、検査だけでは答えにくい問いにデータに基づいた答えを提供します。
Gartner はまた、テスト生成をレガシーモダナイゼーションにおける AI の最も実用的かつ即効性の高い活用法の 1 つとして挙げています。具体的には、マイグレーション開始前に、レガシーコードから動作ベースラインを作成するためのテストを生成するというものです。 CRAP スコアはそのプロセスをより効率的にします。コードベース全体に無差別にテストを生成するのではなく、スコアが最も高く未検出の欠陥リスクが大きい関数に絞ってその労力を集中できます。
セーフティクリティカルなソフトウェアでは、リスクはさらに高まります。自動車、航空、医療機器、産業オートメーションの分野では、複雑で未テストのコードに潜む欠陥はバグレポートで終わりません。製品リコール、認証失敗、安全インシデントに発展する可能性があります。構造的リスクとカバレッジのギャップを結びつけるメトリクスは、実用的な優先順位付けツールであると同時に、テスト戦略の根拠として説明責任を果たせる形を提供します。 ISO 26262、 IEC 62304、 DO-178C といった規格が厳密性の証拠を求める中で、その重要性はますます高まっています。
「私たちは皆、同じ問題を抱えています。カバレッジデータはある。でも、それをどう使えばいいかわからない。」
これが、ダッシュボードの数字が示す以上に、ほとんどのチームの正直な現状です。カバレッジを測定するためのツールは以前から存在しています。しかし欠けていたのは、生の数値を実行可能なリスク情報に変換する層——テストされた量ではなく、正しいものがテストされているかどうか——でした。
CRAP メトリクスはコードカバレッジに文脈を与えます。フラットなパーセンテージを、次のリリース前に対処すべき関数のランク付きリストへと変換するのです。シンプルなコードの高カバレッジは、欠陥が最も潜みやすく、リリース後に発見されたときのコストが最も高い、複雑でクリティカルなパスのカバレッジに比べれば、意味がはるかに小さいのです。その区別に、今やスコアが与えられました。そして、それを表すソートされたリストも。
Gartner content referenced in paraphrased form in accordance with Gartner's content compliance policy. Gartner does not endorse any vendor, product or service depicted in its research publications. Gartner research publications consist of the opinions of Gartner's research organisation and should not be construed as statements of fact.