決定版:いろいろなテストカバレッジ

いきなり「決定版」なんて大風呂敷です(笑)
最近、テストカバレッジの条件カバレッジと複合条件カバレッジについてご質問をいただきました。かねてよりカバレッジの定義は、著名な方でも異なっていることがあると感じていたのですが、Webマガジンなどの記事がJSTQBの試験勉強する方を混迷へ導いているようです。私が見つけたのとご質問された方に教えていただいたのですでに2つの出版社のWeb記事がISTQB(JSTQB)とは違う解説をしています。JSTQBのメンバーが書いたものもあり、う〜んショック。
とりあえず日本の記事は忘れてください(笑)
で、こんなこともあり、お返事で書いたISTQBのカバレッジの定義をご紹介したいと思いました。時間の都合で、この日記は今後もアップデートしていって最終的に決定版になればと思います。

まずコード例1)
 statement1;
 if( (a>0) or (b>0) ){
   statement2;
 }
 statement3;

最初の一歩
ステートメントカバレッジ
カバレッジの最初の一歩。命令網羅とも呼ばれます。
ようするにプログラムのステートメントに着目して、なんステートメント分のなんステートメントを通過(実行)したでパーセンテージを計ります。コード例でテストケースをあげると、

・テストケース1:a>0、b=<0

または

・テストケース2:a<=0、b>0

のどちらかでステートメントカバレッジ100%となります。察しのとおりif文が成立していないケースはテストされません。
私が気になるのが3項演算子

a = ( (b<0) || (c<0) ) ? 100 : 0;

これって1ステートメントですよね?でもif文で書くと

 if( (b<0) || (c<0) ){
   a = 100;
 }else{
   a = 0;
 }

で2ステートメントになります。プログラマによってカバレッジがブレますね。
 
デシジョンカバレッジ
ステートメントではなく、条件分岐に着目します。なん分岐分のなん分岐を通過したかでパーセンテージを計ります。ここで言う分岐はif文などを指します。if文が成立した時と、しない時で、ひとつのif文あたり2つでカウントします。注意点としては、コード例のようにelseのステートメントが無くてもif文が成立しない時を網羅しなければならない点です。ですのでステートメントカバレッジであげたテストケース1かテストケース2だけですとデシジョンカバレッジ50%ということになります。さらに注意点です。ISTQB(JSTQB)のシラバスではブランチカバレッジと同義としていますが、用語集では区別していますが説明意味不明です。ISTQBのメンバーが書いた「ISTQBシラバス準拠 ソフトウェアテストの基礎」にちょっと手がかりがありました。

デシジョンカバレッジは条件付きのブランチのカバレッジを測定しますが、ブランチカバレッジは条件付きと無条件のブランチ両方のカバレッジを測定します

というように区別しているようです。原文みていないのでわかりませんが無条件とはgoto文とかかしら。exceptionはおそらく条件付きの仲間でしょうね。
GUIとか組み込みのイベント割り込みとか、3項演算子も条件付きでしょうね。。。。
 
条件カバレッジ
訳さずコンディションカバレッジと呼ぶことも多いです。ここでいう条件というのはコード例の
 if( (a>0) or (b>0) ){
の(a>0)とか(b>0)とか or を指し、(a>0)とか(b>0)のようなtrue/false状態の最小単位をJSTQBでは単一条件、ISTQBではsingle conditionと呼びます。
 
ここからが混迷の話。。。。
ISTQB作成JSTQB翻訳の用語集では、

条件カバレッジを100%にするには、各判定文の全ての単一条件に対し、真と偽をテストする必要がある。

と書いてあり、複合条件カバレッジ(multiple condition coverage)の定義では

ひとつの命令文中で、全ての単一条件の組み合わせを実施したパ−センテ−ジ

と書いてあり、この文だけでは2つの違いについていろいろな理解をしてしまうようです。
 
たとえば、すべての単一コンディションがtrueのテストケースと、falseのテストケースのたったの2つで条件カバレッジは100%達成と思えてきます。どちらかなら50%。もっとif文50個ほどあって、単一条件が100個ほどあったとしても2つのテストケースで100%達成です。複合条件カバレッジの定義もこの説に追い打ちをかけます。
でも、、なんか変な気がしませんか?
目的に立ち返って「テストカバレッジはなぜ必要か?」を考えてみます。「すべてテストすることは不可能」なのと「ソフトウェアの用途によって品質(テスト量)は変えるべき」だから、その戦略(テスト戦略)の一環としてテストカバレッジを考えわけです。ですのでテストカバレッジ、すくなくともナントカカバレッジと名付けるならば、戦略を立てるのに意味が無いとだめです。まずこの点で全部true、全部false戦略は、私には無意味なように思えます。
 
というわけで、ISTQBのシラバスを書いてるISTQBのプレジデントのレックス・ブラックさんの本「ソフトウェアテスト実践ワークブック」に答えがありました。

  • Rex Black本より引用

条件カバレッジ
プログラム内の分岐判定の中には、単一条件ではなく、複数の条件に基づくものがある。各条件が真と偽のそれぞれの場合の動作を評価したときに、100%条件カバレッジが達成される。言い換えると、ifステートメントを制御する条件式が(A>0)&&(B<0)であったならば、起こりえる4通りの組み合わせの真&&真、真&&偽、偽&&真、偽&&偽のすべてをテストする必要がある。

用語集の条件カバレッジの定義とほぼ同じ「各条件(each single condition)が真と偽のそれぞれの場合の動作を評価したときに、100%条件カバレッジが達成される。」と書いていますが、例は4通りの組み合わせをあげています。
わたしのコード例に対しては、次の4ケースで100%と言えます。

・テストケース1:a>0、b=<0
・テストケース2:a<=0、b>0
・テストケース3:a>0、b>0
・テストケース4:a<=0、b=<0

同様の説明が、ISTQBのシラバスの参考文献としてあげているCem Kaner,Jack Falk,Hung Quoc Ngugenの「基本から学ぶソフトウェアテスト」にもありました。この書籍では、ステートメントカバレッジ、ブランチカバレッジに対して「更に強力な網羅基準である」とし、同様の例をあげています。

IF( A < B and C = 5 )
THEN do SOMETHING
SET D = 5
 
(a)A < B and C = 5 (SOMETHINGを実行し、Dに5をセット)
(b)A < B and C != 5 (SOMETHINGを実行せず、Dに5をセット)
(c)A >= B and C = 5 (SOMETHINGを実行せず、Dに5をセット)
(d)A >= B and C != 5 (SOMETHINGを実行せず、Dに5をセット)
 
条件網羅は更に強力な網羅基準であり、条件分岐において条件の真・偽のすべての組み合わせをチェックする。この例では、4つのケースをすべてテストしなければならない。

 
ど−−も、each single conditionのとりかたが、混迷の元のような気がします。
これは日本人だけかしら。。。
 
複合条件カバレッジ
これもレックス・ブラックさんの本の説明のほうがよくわかります。

  • Rex Black本より引用

先行する条件判定しだいで後続の条件が判定されない可能性のあるC++のような言語の場合、100%条件カバレッジは必ず意味があるとは限らない。その場合、制御フローの観点から条件判定に影響しうる条件だけをカバーする。

ようするにコード例の
 if( (a>0) or (b>0) ){
で(a>0)の時、仮にこれがC言語javaなど今時の言語とするならば、(b>0)は評価されないから省いてカバレッジを考えて良いということです。
コード例では、

・テストケース1:a>0、Don't Care
・テストケース2:a<=0、b>0
・テストケース3:a<=0、b=<0

の3つで100%です。単一条件が増えれば、意味もなく倍々で増える条件カバレッジに対して、もうちょっと頭を使って効率よくしたのが複合条件カバレッジと言えるかと思います。単体テストではよく使われる戦略だと思いますが、今回のコード例のように明示的にカッコをつけていないと、意外な演算子が意外な評価順序だったりして手痛い目にあったこと多々あります。(^^ゞ
 
とりあえずここまで。
他のカバレッジも追記していって「決定版」目指します!