C0/C1/C2カバレッジとは
テストカバレッジがどんなものかは、他の記事を読んでください。 その上で、テストケースの分類―C0,C1,C2について説明します。
以下のようなコードのテストケースを考えて見ます。
function hogepiyo(input1, input2) { //条件分岐1 if (input1 > 10) { //処理1 } else { //処理2 } //条件分岐2 if (input1 % 2 == 0 || input2 % 3 == 0) { //処理3 } else { //処理4 }
}
C0: 命令網羅率(statement coverage)
全ての処理(命令)をテストするカバレージのことをC0と呼びます。
処理に着目して、すべての処理が1回以上実行されるような条件でテストケースを作成します。 上記のコード例で、C0を満たすテストケースを書くためには、少なくとも処理1・処理2・処理3・処理4は1回以上テストを通す必要があるということです。
例えば、
- input1=12として、処理1と処理3をチェック
- input1=9として、処理2と処理4をチェック
の2パターンをテストすることで、C0を網羅できます。
入力条件 | 条件分岐1 | 条件分岐2 |
---|---|---|
input1=12 | True | True |
input1=9 | False | False |
C1: 分岐網羅率(branch coverage)
条件分岐に注目して、条件式のすべての組み合わせをテストするカバレージのことをC1と呼びます。
条件に着目して、全ての条件についてTrue/False等の判定結果を網羅するようにテストケースを作成します。 上記のコード例では、C1を満たすテストケースを書くためには、(処理1&処理3)、(処理1&処理4)、(処理2&処理3)、(処理2&処理4)を通る4ケースが必要ということです。
例えば、
- input1=12
- input1=13
- input1=9
- input1=8
入力条件 | 条件分岐1 | 条件分岐2 |
---|---|---|
input1=12 | True | True |
input1=13 | True | False |
input1=9 | False | True |
input1=8 | False | False |
の4パターンをテストすることで、C1を網羅できます。
C2: 条件網羅率 (condition coverage)
条件分岐内の条件に着目して、全ての条件結果をテストするカバレージのことをC2と呼びます。 分岐網羅率(C1)との違いは、ANDやORで複数の条件が結ばれていても、それぞれを独立した条件と見なします。
条件分岐2に着目すると、2つの条件がORで結ばれています。
input1 % 2 == 0 || input2 % 3 == 0
C1ではこの条件式を1つとして見なして、True/Falseの結果を確認するが、C2では別々の条件として考えます。 つまり、
- input1=12
- input1=13
- input2=3
- input2=4
とすることで、この2つの条件式を内包する条件分岐のテストパターンを網羅できます。
もちろん最終的には、条件分岐1(input1 > 10
)も含めて考える必要があるため、テストケースの総数は8となります。
- 条件分岐1では2パターン
- 条件分岐2では4パターン
- 条件分岐1 × 条件分岐2 = 8パターン
input1 | input2 | 条件分岐1 | 条件分岐2 (input1 % 2 == 0) |
条件分岐2 (input2 % 3 == 0) |
|
---|---|---|---|---|---|
12 | 3 | True | True | True | |
12 | 4 | True | True | False | |
13 | 3 | True | False | True | |
13 | 4 | True | False | False | |
8 | 3 | False | True | True | |
8 | 4 | False | True | False | |
9 | 3 | False | False | True | |
9 | 4 | False | False | False |
どこまでテストすべきか?
テストカバレージ100%と言っても、C0,C1,C2のどの条件下でテストケースを書くかでは、精度やテストケース数が異なります。
上記のコードを誤って、以下のように間違えたとしましょう。
//条件分岐2 if (input1 % 2 == 0 || input2 % 6 == 0) { ^^^ //処理3 } else { //処理4 }
}
C1の条件下でテストケースを書いた際に、以下のようなパターンでチェックしていた場合、結果はすべて期待通りの動きをします。
- input1=12 //処理1と処理3
- input1=13 //処理1と処理4
- input1=3 //処理2と処理3
- input1=4 //処理2と処理4
そして、コードカバレッジ100%となるわけです。(こんなテストをしていたらプログラマー失格ですが)
ここまで読んでいれば分かりますが、input2=3
とした場合に、期待どおりには動かずバグとして発見されます。
結果として、コードカバレッジ100%なのにバグが見つかって、バグ報告と修正にかかる手間が残るのです。
バグが発生した際の、バグ調査や修正にはそれ以上の時間がかかる可能性があると考えると、きちんとテストはすべきだと言えます。 また、同様に、どのようなテストをすべきか―C0,C1,C2のどの条件を使うかの認識を、プログラマー同士で合わせておくことも大切と言えそうです。