テストスイートが通過し、カバレッジレポートが高い数値を示している場合、コードが十分にテストされていると簡単に思い込んでしまいがちです。しかし実際には、コードカバレッジの指標は、しばしば誤った安心感を与えることがあります。
コードカバレッジは、ソースコードのどの部分がテストによって実行されたかを測定しますが、実行されたこと自体が正しさを保証するわけではありません。重大な盲点を避けるためには、カバレッジが実際に何を測定し、何を測定しないのか、そしてそれを効果的に活用する方法を理解することが不可欠です。
定義
コードカバレッジとは、自動テストまたは手動テスト中に実行されたソースコードの割合を測定するソフトウェア品質指標です。開発者がコードベースの未テスト部分を特定するのに役立ち、信頼性の向上と欠陥の削減に貢献します。Cocoなどのコードカバレッジツールは、どの文、分岐、条件が実行されたかを示す詳細なレポートを提供します。これらの知見により、チームはテストの完全性を向上させ、堅牢なソフトウェア品質を維持することが可能となります。
コードカバレッジは、テスト実行時にソースコードのどの部分が実行されたかを示します。カバレッジは、開発者にとってデバッガーが果たす役割と同様の役割をテスターに対して果たすとお考えください。
特定のコードがテストで実行された場合、そのコードはカバレッジ対象と見なされます。カバレッジは、未テストの部分、潜在的なデッドコード、および冗長なテストを削除できる領域を特定するのに役立ちます。
しかし、多くのチームが見落としている重要な違いがあります。カバレッジはどのコードが実行されたかを示すものであり、そのコードが正しく検証されたかどうかを示すものではありません。関数が完全に実行されていても、テストがその動作について意味のあることを何も確認していない可能性があります。
関数が呼び出されたか、またその頻度を測定します。100%の関数カバレッジを達成することは、すべての関数が少なくとも一度は実行されたことを確認するものであり、デッドコードや未使用コードを発見するのに有用です。ただし、どの関数も正しく動作したことを保証するものではありません。
実行可能なコードを含む行のうち、実際に実行された行を測定します。この指標はフォーマットの影響を強く受けます。1行に複数の文が含まれる場合があり、同一のロジックでもフォーマットが異なると結果が大きく異なることがあります。その結果、行カバレッジはチーム間の比較や徹底の指標としては信頼性が低いと言えます。
ステートメントカバレッジは、常に一緒に実行されるステートメントをグループ化し、コードの書式設定に関わらず、実行可能なすべてのステートメントが実行されることを保証します。これによって書式設定の問題に対処します。
Coco Code Coverageツールのドキュメントでは、これはしばしばステートメントブロックカバレッジと呼ばれます。これは、ステートメントを常に一緒に実行されるブロックにグループ化するからです。
ステートメントカバレッジは、コーディングスタイルを超えてより一貫したメトリクスを生成しますが、それでもなお、すべての論理パスがテストされたことを保証するものではありません。
高いカバレッジ数値は、測定対象が不適切なレベルである場合、誤解を招く可能性があります。重要な動作が実際にテストされたという証拠がないにもかかわらず、チームに過信を招く恐れがあります。
こちらの専門家のブログ記事で、コードカバレッジのパーセンテージが示す真の意味について、より深くご理解いただけます。これらの数値が実際に何を意味するのか、また「100%のステートメントカバレッジ」が保証するものとしないものについて、詳しく解説します。
判定カバレッジでは、あらゆる判定の双方(真と偽)の結果についてテストを実施する必要があります。ここでカバレッジ分析は意味のある欠落を明らかにし始めます。多くのチームは「正常経路」のみをテストし、エラー処理を見逃しがちです。判定カバレッジは両方の経路の検証を強制し、より単純な指標では見逃される論理エラーをしばしば発見します。ほとんどのチームにとって、この指標は実用性と洞察力のバランスが最も取れています。
条件カバレッジは複雑な判断を個々の条件に分解します。単に「アクセス許可」と「アクセス拒否」をテストするのではなく、各構成条件(例:ログイン済み、権限付与済み、有効期限切れでない)が真と偽の両方で評価されていることを検証します。これにより、予期せぬ抜け穴が明らかになることがよくあります。
MCCでは、決定におけるあらゆる可能な条件の組み合わせをテストする必要があります。条件が3つある場合、それは8つのシナリオに相当します。さらに2つ追加すると、32のシナリオになります。MCCは複雑さが急速に増大する可能性があるため、選択的に使用されるのです。
MC/DCはより賢明なバランスを提供します。あらゆる組み合わせをテストする代わりに、個々の条件が意思決定の結果に独立して影響を与えることを証明することを求めます。レシピが機能することを知るために、全ての材料の組み合わせを試す必要はありません。各材料を除去した際に結果が変化することを示すだけで十分です。MC/DCはコードに対しても同様の役割を果たし、数千ものシナリオを必要とせずに強力な保証を提供します。安全性が極めて重要なソフトウェアにおける最高の基準と見なされています。
これらのカバレッジレベルと、規制環境におけるその適用方法についてより深く議論するには、Qt Group のシニアソフトウェアエンジニア、James Vance 氏の講演をご覧ください。James 氏は、コードカバレッジを念頭に置いたテストへのアプローチ方法を分析し、コードカバレッジの重要なレベルについて説明し、安全性が重要な業界が、信頼性が高く、コンプライアンスに準拠したソフトウェアを確保するために必要な要件を強調しています。
こちらのリンクよりウェビナーの全編にアクセスいただき、実践におけるコードカバレッジの詳細について、以下の内容を含めご確認いただけます
セーフティクリティカルシステムを開発するチームにとって、徹底的なテストは任意ではなく必須です。
規制対象業界以外においても、これらの基準は、重大な欠陥が被害をもたらす前に発見するための数十年にわたる経験から生まれた貴重な指針を提供します。
|
コードカバレッジの利点 |
コードカバレッジの限界 |
|
バグの早期発見 カバレッジ分析により、本番環境で失敗する前に未テストのコードを明らかにします。 |
高いカバレッジ ≠ 高品質なテスト 表面的なチェックで100%カバレッジを達成できます。カバレッジは実行を測定するものであり、検証の品質を測定するものではありません。 |
|
レビューの具体化 レビュー担当者は、仮定だけでなく、どのコードにテストが存在するかを正確に把握できます。 |
動的挙動に関する知見の限界 実行時の条件、設定、環境変数によって駆動される挙動などは、高いカバレッジがあってもテストされない可能性があります。 |
|
戦略的なテストの重点化 カバレッジは、リスクが高くテストが不十分な領域を浮き彫りにします。 |
指標追及による優先順位の歪み パーセンテージが目標となると、チームは実際の欠陥を発見する代わりに、指標を満たすためのテストを書く可能性があります。 |
|
測定による信頼性の構築 カバレッジの推移を追跡し、変更が常にテストされ、欠陥を導入しないことを保証します。 |
|
|
コンプライアンス要件の対応 Cocoは、ISO 26262やDO-178Cなどの規格に準拠した監査対応レポートをサポートします。 |
| 要するに:カバレッジは盲点を明らかにするため、またテストの判断材料として活用してください。ただし、カバレッジが示すのは実際に実行された部分のみであり、テストが何か意味のあることを検証したかどうかは示さないことを忘れないでください。 |
以下に3つの実践的な考慮事項を挙げます。
最も成功しているチームは、カバレッジを診断ツールとして扱います。それは誤った安心感を与えるのではなく、リスクと優先順位についてより良い疑問を提起するものです。
カバレッジに依存される場合、ツールの機能性が重要となります。Cocoは単純なパーセンテージを超え、カバレッジを実用的なものにするため、以下の機能を提供します。
Cocoを活用すれば、チームはテストが実行している部分と未実行部分を正確に把握し、迅速にギャップを埋める対応が可能です。
当社のウェビナー「スマートなテスト戦略」では、先進的なチームがカバレッジ分析を活用し、テスト活動を導き、高リスクコードを特定し、指標に惑わされることなく開発プロセスに測定可能な品質を組み込む方法を実演いたします。
ウェビナーをご覧いただき、これらの原則が実際にどのように機能するかをご確認ください。
GitHub Copilot + Coco Code Coverageを活用してテストカバレッジを65%から78%に高める方法、およびこのアプローチを安全性が極めて重要な分野を含む他のフレームワークや業界に適用する方法についてご紹介します。
100%のステートメントカバレッジの意味を理解していても、それはテストパズルの一部に過ぎません。真の品質を測るには、テストカバレッジとテスト効果性、そしてこれら3つの指標が相互にどう作用するかを考慮する必要があります。ブログ記事「コードカバレッジ vs. テストカバレッジ vs. テスト有効性:何を測るべきか」では、各指標の詳細、重複する部分、そしてこれらを1つの実用的なワークフローに統合する方法について解説しています。