コードカバレッジを用いて、テストケースの網羅性を測定する
カバレッジとは、対象のソフトウェアがテストによってどれだけ実行されたかを割合で表したものです。
ソフトウェアの単体テストでは、ソースコードの網羅率を示し、コードカバレッジと呼ばれます。コードカバレッジにはいくつもの種類がありますが、今回は「ステートメントカバレッジ(命令網羅/C0)」「デシジョンカバレッジ(分岐網羅/C1)」「MC/DC」を測定します。これらの用語の意味を表3にまとめました。
| 測定項目 | 意味 |
|---|---|
| ステートメントカバレッジ(SC) | すべての実行可能命令(ステートメント)のうち、テストで実行された命令の割合 |
| デシジョンカバレッジ(DC) | すべての判定条件のうち、テストで実行された判定条件の割合 |
| MC/DC |
航空機ソフトウェアのテストで用いるカバレッジ基準として考案され、国際技術標準 DO-178B(RTCA)では次の3つの条件を満たすものと定められています。
|
今回、検証に用いたソースコードはOSSであるOpenSSLを対象とし、因子数が異なる関数を選定の上、オールペア法を用いて組み合わせテストケースを作成しました。その組み合わせテストケースに対して、それぞれ単体テストを実行し、3つの関数でそれぞれどの程度網羅されているか確認します。
オールペア法を適用した組み合わせテストケースの作成にはMicrosoft社の「PICT(Pairwise Independent Combinatorial Testing tool)」を使用しました。
単体テストの実行およびカバレッジの計測はParasoft社の「C++test」を使用しました。
C++testでは、テストケースで設定する事前条件や事後条件などの入力データをExcelやCSVといった外部ファイルから読み込むことができるため、PICTを用いて作成した入力データ(CSVファイル)をそのまま単体テストの事前条件として、単体テストを実行することができます。
図1のようにC++testはテスト対象関数から「どのような型の引数を受け取るか」「どのような型の戻り値か」を解析し、自動でテストケースの枠組みを作成します。同様に、テスト対象関数内で呼び出している関数に対するスタブの枠組みを自動で生成し、テストケースからテスト対象関数の呼び出し、テスト対象関数からスタブの呼び出しの一連の流れを行うテスト用プログラムを自動で実装します。
この生成したテストケースやスタブに対し、テストケースの事前条件と事後条件、スタブの振る舞いなど仕様に基づく入力データをひも付けます。今回は、この入力データをPICTで作成するということになります。
検証に利用したデータとテストケースの生成結果
PICTが作成した入力データを図2に示します。A~E列がオールペア法を用いて作成した入力データです。F列は期待値を設定しました。これがテストの元データになります。このデータをCSVファイルとして保存しておきます。
C++testで作成したテストケースが図3です。データを読み込み、テスト対象関数を呼び出し、その結果を期待値と比較するという処理が自動的に記述されます。
そして、C++testで単体テストを実行します。テストはCSVファイルの行数分、つまりテストケース数分実行されます。その結果は、図4のような画面で確認できます。図4は図2、3のデータを読み込んだ後ではなく、見やすいように別のサンプルを用いた場合の画面を示しています。
続いて、実際に測定した結果を検討します。
カバレッジの測定結果を検討する
オールペア法で自動生成したテストケースに対してC++testを用いてカバレッジを計測しました。3つの関数A~Cに対して検証を行い、その結果は表4~6の通りです。
いずれも組み合わせの因子数が少ないほど、カバレッジは低くなっています。すなわち、組み合わせ因子数が少ないとソースコードを十分に網羅できていないことがわかります。一方で、ある組み合わせ因子数より大きな因子数であってもカバレッジが高くなることはありません。このカバレッジが収束する組み合わせ因子数が、オールペア法で作成したテストケースにおいて、網羅性の観点での最適な数と判断できます。
