ソフトウェアエンジニアリングにおいて、コードカバレッジ(テストカバレッジとも呼ばれる)は、特定のテストスイートを実行したときにプログラムのソースコードがどの程度実行されるかをパーセンテージで表したものです。コードカバレッジが高いプログラムは、テスト中に実行されるソースコードの割合が高く、コードカバレッジが低いプログラムに比べて、検出されないソフトウェアバグが含まれている可能性が低いことを示唆しています。[ 1 ] [ 2 ]テストカバレッジを計算するために、さまざまな指標を使用できます。最も基本的なものとしては、テストスイートの実行中に呼び出されるプログラムサブルーチンの割合とプログラムステートメントの割合などがあります。
コードカバレッジは、体系的なソフトウェアテストのために考案された最初の方法の1つです。最初の発表は、1963年にMillerとMaloneyがCommunications of the ACMで発表したものです。 [ 3 ]
テストスイートによって実行されたコードの割合を測定するために、1つ以上のカバレッジ基準が使用されます。これらは通常、テストスイートが満たさなければならないルールまたは要件として定義されます。[ 4 ]
カバー範囲の基準はいくつかありますが、主なものは次のとおりです。[ 5 ]
例えば、次のC言語の関数を考えてみましょう。
int foo ( int x , int y ) { int z = 0 ; if (( x > 0 ) && ( y > 0 )) { z = x ; } return z ; }この関数はより大きなプログラムの一部であり、そのプログラムはテストスイートとともに実行されたと仮定します。
fooこの実行中に、当該関数が少なくとも1回呼び出された場合、関数カバレッジは満たされます。foo(1,1)。なぜなら、この場合、 を含む関数内のすべての行が実行されるからですz = x;。foo(1,1)。foo(0,1)なぜなら、最初のケースでは両方のif条件が満たされ、z = x;が実行されるのに対し、2番目のケースでは最初の条件で(x>0)あるが満たされないため、の実行が妨げられるからですz = x;。foo(1,0)、、、foo(0,1)およびを呼び出すテストで満たされますfoo(1,1)。これらは、最初のケースでは(x>0)がに評価されtrue、2番目のケースではがに評価されるため必要ですfalse。同時に、最初のケースではとなり、2番目のケースでは(ブール演算子の遅延評価のため)は(y>0)false評価されず、3番目のケースではとなります。(y>0)true短絡評価を行わないプログラミング言語では、条件カバレッジは必ずしも分岐カバレッジを意味するものではありません。例えば、次のPascalコード断片を考えてみましょう。
aとbの場合条件カバレッジは、次の2つのテストによって満たされる。
a=true、b=falsea=false、b=trueしかし、この一連のテストでは、どちらのケースも条件を満たさないため、分岐網羅性を満たしませんif。
テスト中に例外処理コードのすべての条件と分岐が十分に網羅されていることを確認するためには、障害注入が必要になる場合があります。
関数カバレッジと分岐カバレッジの組み合わせは、決定カバレッジとも呼ばれることがあります。この基準では、プログラム内のすべてのエントリポイントと出口が少なくとも 1 回呼び出され、プログラム内のすべての決定がすべての可能な結果を少なくとも 1 回取っている必要があります。この文脈では、決定は条件と 0 個以上のブール演算子で構成されるブール式です。この定義は分岐カバレッジとは異なりますが[ 6 ] 、決定カバレッジという用語は、その同義語として使用されることがあります[ 7 ] 。
条件/決定カバレッジでは、決定カバレッジと条件カバレッジの両方を満たす必要があります。しかし、安全性が極めて重要なアプリケーション(航空電子機器ソフトウェアなど)では、修正条件/決定カバレッジ(MC/DC)を満たすことが求められる場合がよくあります。この基準は、条件/決定基準に、各条件が決定結果に独立して影響を与えるべきであるという要件を追加したものです。
例えば、次のコードを考えてみましょう。
( aまたはb )かつcの場合以下のテストによって、条件/判定基準が満たされる。
しかし、上記のテストセットでは、修正条件/決定カバレッジを満たしません。なぜなら、最初のテストでは「b」の値が、2番目のテストでは「c」の値が出力に影響を与えないからです。したがって、MC/DCを満たすには、次のテストセットが必要です。
この基準では、各決定に含まれる条件のすべての組み合わせをテストする必要があります。例えば、前のセクションのコード断片では、8つのテストが必要になります。
パラメータ値カバレッジ(PVC) では、パラメータを受け取るメソッドで、そのパラメータの一般的な値をすべて考慮する必要があります。つまり、パラメータの一般的な値をすべてテストするという考え方です。[ 8 ]例えば、文字列の一般的な値には、1) null、2) 空、3) 空白 (スペース、タブ、改行)、4) 有効な文字列、5) 無効な文字列、6) シングルバイト文字列、7) ダブルバイト文字列などがあります。非常に長い文字列を使用することも適切かもしれません。考えられるパラメータ値をすべてテストしないと、バグが発生する可能性があります。これらのうち 1 つだけをテストすれば、各行がカバーされるためコードカバレッジは 100% になりますが、7 つのオプションのうち 1 つしかテストされないため、PVC は 14.2% にしかなりません。
さらに、適用範囲に関する基準は存在するが、それらはあまり頻繁には使用されない。
安全性が重視されるアプリケーションや信頼性が求められるアプリケーションでは、何らかのテストカバレッジが 100% であることが求められることがよくあります。たとえば、ECSS -E-ST-40C 規格では、4 つの異なる重要度レベルのうち 2 についてはステートメントと決定のカバレッジが 100% であることが要求されています。残りのレベルについては、目標カバレッジ値はサプライヤーと顧客の間で交渉されます。[ 11 ] しかし、特定の目標値、特に 100% を設定することは、さまざまな理由で実務者から批判されています (cf. [ 12 ] )。 Martin Fowler は次のように書いています。「100% のようなものには疑念を抱くでしょう。カバレッジの数値を満足させるためにテストを書いているだけで、何をしているのか考えていない人の匂いがするからです。」[ 13 ]
上記のカバレッジ基準の中には、相互に関連するものがあります。例えば、パスカバレッジは、決定カバレッジ、ステートメントカバレッジ、およびエントリー/エグジットカバレッジを意味します。決定カバレッジはステートメントカバレッジを意味します。なぜなら、すべてのステートメントは分岐の一部だからです。
上記のような完全なパスカバレッジは、通常、非現実的または不可能です。決定は最大で内部のパス。ループ構造は無限のパスを生み出す可能性がある。また、多くのパスは実行不可能である可能性があり、それはテスト対象プログラムにその特定のパスを実行させる入力がないことを意味する。しかし、実行不可能なパスを識別するための汎用アルゴリズムは不可能であることが証明されている(そのようなアルゴリズムは停止問題の解決に使用できる)。[ 14 ]基本パステストは、たとえば、完全なパスカバレッジを達成せずに完全なブランチカバレッジを達成する方法である。[ 15 ]
実用的なパスカバレッジテストの方法では、ループ実行回数のみが異なるコードパスのクラスを特定しようとし、「基本パス」カバレッジを達成するには、テスターはすべてのパスクラスを網羅する必要があります。[ 16 ]
対象ソフトウェアは、特別なオプションやライブラリを使用して構築され、制御された環境下で実行され、実行されたすべての関数をソースコード内のファンクションポイントにマッピングします。[ 17 ]これにより、通常の条件下ではほとんどアクセスされない、またはまったくアクセスされない対象ソフトウェアの部分をテストすることができ、最も重要な条件(ファンクションポイント)がテストされたことを確信できます。結果の出力は、実行されていないコード領域を確認するために分析され、必要に応じてこれらの領域を含めるようにテストが更新されます。他のテストカバレッジ方法と組み合わせることで、厳密でありながら管理しやすい回帰テストのセットを開発することを目的としています。
ソフトウェア開発環境においてテストカバレッジポリシーを導入する際には、以下の点を考慮する必要があります。
ソフトウェア開発者は、テストカバレッジの結果を参考に、重要な機能のカバレッジを高めるための追加のテストや入力セット、構成セットを考案できます。テストカバレッジには、ステートメント(または行)カバレッジとブランチ(またはエッジ)カバレッジという2つの一般的な形式があります。行カバレッジは、テストを完了するために実行されたコード行という観点から、テストの実行フットプリントを報告します。エッジカバレッジは、テストを完了するために実行されたブランチまたはコード決定ポイントを報告します。どちらも、パーセンテージで測定されるカバレッジメトリックを報告します。この意味は、使用されたカバレッジの形式によって異なります。例えば、67%のブランチカバレッジは、67%のステートメントカバレッジよりも包括的です。
一般的に、テストカバレッジツールは実際のプログラムに加えて計算とログ記録を行うため、アプリケーションの動作が遅くなります。そのため、通常、このような分析は本番環境では行われません。当然のことながら、これらのカバレッジテストを現実的に適用できないソフトウェアの種類も存在しますが、直接テストではなく分析によってある程度のカバレッジマッピングを近似することは可能です。
こうしたツールによって影響を受ける欠陥もいくつか存在する。特に、テスト環境で実行すると、一部の競合状態や同様のリアルタイム処理が隠蔽される可能性がある。ただし、逆に、テストコードのオーバーヘッドが増えることで、これらの欠陥の一部が発見しやすくなる場合もある。
ほとんどのプロのソフトウェア開発者は、C1 および C2 カバレッジを使用します。C1 はステートメント カバレッジ、C2 は分岐または条件カバレッジを表します。C1 と C2 を組み合わせることで、コード ベース内のほとんどのステートメントを網羅できます。ステートメント カバレッジは、エントリと終了、ループ、パス、状態フロー、制御フロー、データ フローのカバレッジを含む関数カバレッジも網羅します。これらの方法を使用すると、ほとんどのソフトウェア プロジェクトでほぼ 100% のコード カバレッジを達成できます。[ 19 ]
試験範囲は、航空電子機器の安全認証における考慮事項の 1 つです。連邦航空局(FAA)による航空電子機器の認証に関するガイドラインは、DO-178B [ 18 ]およびDO-178C [ 20 ]に記載されています。