ホワイトボックステストにおけるカバレッジとテストケース(C0, C1, C2, CDC, MC/DC, MCC)
ホワイトボックステストでよく用いられる網羅率(coverage)について、違いがよくわかっていなかったためまとめてみました。間違いあれば更新します。
網羅率(coverage, カバレッジ)とは
カバレッジは、所定の網羅条件がテストによってどれだけ実行されたかを割合で表したものです。
(中略)
テストを実施するにあたって、カバレッジ (網羅率)を測定/分析することは、ソフトウェアの品質向上に非常に大きな意味を持ちます。(略) テストのカバレッジを測定する方法は、コードや仕様、要件、設計など、さまざまな側面から計測する方法がありますが、単体テスト段階では、コードベースのカバレッジでテストの品質を測ることが一般的です。
引用元:https://www.techmatrix.co.jp/t/quality/coverage.html
要はソフトの品質を担保するための一つの指標です。まともなソフト開発現場なら必ずやっている工程だと思われますが、どこまで(何を基準に)確認するかはソフトがどのような使われ方をするかに依存します。そこまでバグ影響の大きくないwebサービスとかなら、細かい品質より開発スピード重視するだろうし、逆に命に関わる組み込み系製品のソフトならカバレッジの基準が厳密にプロセスで定義されていたりします。
カバレッジ基準
実際のコード例とともに、よく用いられるカバレッジの測定方法について説明します。
以下のようなコードを想定し、各カバレッジを100%とするためのテストケースについて考えます。
if (a1 and a2) or a3: # 判定条件A statementA_T else: statementA_F if b1 or b2: # 判定条件B statementB_T
フローチャートだと以下のようになります。
ここでは、ifの分岐を決定する文を判定条件、その中の個々の判定を条件式と呼ぶことにします。例では判定条件Aは条件式a1, a2, a3の三つで構成されていることになります。
例での命令文はstatementA_T, statementA_F, statementB_Tの三つです。
命令網羅 : statement coverage (C0)
全ての命令文が少なくとも一回実行されるようなテストを実施します。C0, SCとも呼ばれます。例のコードでC0カバレッジ 100%とするためには、例えば以下のテストケースが必要です。
No. | a1 | a2 | a3 | b1 | b2 |
---|---|---|---|---|---|
1 | False | False | True | True | False |
2 | False | False | False | True | False |
上記のケースでは以下のように分岐が実行されます。
見ればわかる通り、基準としては一番ゆるいものです。
判定条件網羅 : decision coverage(C1)
全ての判定条件の真偽が少なくとも一回実行されるようなテストを実施します。C1, DCとも呼ばれます。日本語では分岐網羅(branch coverage)とも呼ぶそうです。この後説明する基準と対応付けやすいので、decision coverageで覚えたほうがいいかも。例のコードでC1カバレッジ100%とするためには、例えば以下のテストケースが必要です。
No. | a1 | a2 | a3 | b1 | b2 |
---|---|---|---|---|---|
1 | False | False | True | False | False |
2 | False | False | False | True | False |
上記のケースでは以下のように分岐が実行されます。
C1カバレッジが100%になると、必然的にC0カバレッジも100%となります。
条件網羅 : condition coverage(C2)
全ての条件式の真偽が少なくとも一回実行されるようなテストを実施します。C2, CCとも呼ばれます。例のコードでC2カバレッジ100%とするためには、例えば以下のテストケースが必要です。
No. | a1 | a2 | a3 | b1 | b2 |
---|---|---|---|---|---|
1 | True | True | False | True | False |
2 | False | False | True | False | True |
上記のケースでは以下のように分岐が実行されます。
意図的にダメなパターンを挙げました。C2カバレッジが100%となってもC0, C1カバレッジが100%とならないこともあります。この後説明する基準があればC2いらなくね…?と思わなくもないです。
判定条件/条件網羅 : condition / decision coverage(DC/CC, CDC)
全ての条件式の真偽と、全ての分岐が少なくとも一回実行されるようなテストを実施します。見ての通り、C1とC2を組み合わせたものです。日本語だと意味不明になりがちなので、DC/CCかCDCで統一してほしいです。例のコードでDC/CCカバレッジ100%とするためには、例えば以下のテストケースが必要です。
No. | a1 | a2 | a3 | b1 | b2 |
---|---|---|---|---|---|
1 | False | True | False | False | False |
2 | True | False | True | True | True |
ぱっと見これで十分な気もしますが、まだあります。
改良条件判定網羅 : modified condition/decision coverage(MC/DC)
以下を満たすようなテストを実施します。
全ての判定条件の真偽が少なくとも一回実行される(C1)
全ての条件式の真偽が少なくとも一回実行される(C2)
全ての条件式が、単独で全体の判定条件の結果を左右する
3つめがわかりにくいですね。要は X or Y みたいな判定条件があったときに、XとYが両方Trueみたいなケースを選んでしまうと「実際に各条件式が機能しているかどうか」がわからなくなります。それを確認できるようなケースを選びましょう、ということです。
例のコードでMC/DCカバレッジ100%とするためには、例えば以下のテストケースが必要です。
No. | a1 | a2 | a3 | b1 | b2 |
---|---|---|---|---|---|
1 | True | False | False | True | False |
2 | False | True | False | False | True |
3 | True | True | False | True | True |
4 | True | False | True | True | True |
それぞれのケースは、以下のように条件判定に影響します。
No. | a1 | a2 | a3 | a1 and a2 | 判定条件A | b1 | b2 | 判定条件B |
---|---|---|---|---|---|---|---|---|
1 | - | 〇 | 〇 | False | False | 〇 | - | True |
2 | 〇 | - | - | False | False | - | 〇 | True |
3 | 〇 | 〇 | - | True | True | 〇 | 〇 | False |
4 | - | - | 〇 | False | True | - | - | False |
めちゃわかりにくい表ができてしまった…
それぞれのケースがどの条件式についての確認なのかを〇印で示しています。「単独で全体の判定条件の結果を左右する」かどうかは、全体の判定条件が真(または偽)になる条件式の組み合わせから対象の条件式のみ論理を変え、全体の判定条件の論理が反転することで、初めて確認できます。
例えばa1の条件式が「単独で全体の判定条件の結果を左右する」ことは、No.2とNo.3を比較するとわかります。No.2とNo.3は(判定条件の中で)a1以外の論理は等しく、a1が反転すると判定条件Aも反転しています(=全体の判定条件結果が変わる)。条件式がn個ある場合、MC/DCカバレッジを100%とするためには少なくともn+1ケースは必要です。
複合条件網羅 : multiple condition coverage(MCC)
全ての条件式の真偽が取りえる全ての組み合わせを、少なくとも一回実行するようなテストを実施します。条件式の数だけ、2のべき乗でパターンが増えていくのでこちらのほうがわかりやすいですね。
例のコードでMCCカバレッジ100%とするためには、例えば以下のテストケースが必要です。
No. | a1 | a2 | a3 | b1 | b2 |
---|---|---|---|---|---|
1 | False | False | False | False | False |
2 | False | False | True | False | True |
3 | False | True | False | True | False |
4 | False | True | True | True | True |
5 | True | False | False | False | False |
6 | True | False | True | False | True |
7 | True | True | False | True | False |
8 | True | True | True | True | True |
判定条件Aには3つの条件式が含まれているので、23=8通りのパターンが必要です。判定条件Bは4通りなので、この8通りの中で全パターンを通すことができます。
経路組み合わせ網羅 : path coverage
コード内の全ての制御パスが少なくとも一回実行されるようなテストを実施します。ここで言う制御パスは命令文だけでなく、条件式も該当します。つまり「プログラムが実行しうるパス」を全て試すのがこのテストです。
例のコードでパスカバレッジ100%とするために必要なケースは…多いので書きません。MCCで説明した(判定条件Aの8通り) × (判定条件Bの4通り) = 32通りのテストケースが必要です。見て分かる通り、テストケースが膨大になりがちなので、実際の開発等で使われることはほぼないでしょう。
まとめ
ホワイトテストの判断基準であるカバレッジについて一通り説明しました。当然ですが、基準を厳しくすればするほどテスト工数が増加するため無闇に厳しくすればよいというわけではないです。仕様や要件と相談して決める必要があります。
余談ですが、車載や航空系等の高信頼性が求められる分野では最低でもMC/DCレベルが求められます。車載ではISO26262という国際規約で定められていたりします。ただMC/DCはテスト設計が難しくなりがちなので、いっそのことMCCを採用したほうが幸せになれるかもしれません。
参考
https://www.itmedia.co.jp/im/articles/1111/07/news142.html