はじめに
テストの話をしていると、
「C0」「C1」「C2」という言葉が出てくることがあります。
なんとなく
- C0 → 行を通る
- C1 → 分岐を通る
- C2 → 条件を見る
というイメージはあっても、実際にコードで考えると少し分かりにくいです。
この記事では、簡単なコードを使って
「それぞれ何を確認しているのか」を整理します。
サンプルコード
まずは例として次の関数を考えます。
function discount(price, isMember) {
if (price > 1000 && isMember) {
return price * 0.9;
}
return price;
}
この関数は
- 1000円より高い
- かつ会員
のときだけ10%割引になります。
ここには2つの条件があります。
price > 1000
isMember
このコードを使ってカバレッジを見ていきます。
C0カバレッジ(命令網羅)
C0はシンプルで、
すべての命令が一度でも実行されればOK です。
例えば次のテスト。
discount(2000, true);
この場合、
if (price > 1000 && isMember) {
return price * 0.9;
}
の中も実行されるので、
コードの行はすべて通ります。
つまり C0は満たしています。
ただし、このテストだけだと
「割引されないケース」は確認していません。
C0は最低限の確認、というイメージです。
C1カバレッジ(分岐網羅)
C1では
分岐のtrueとfalseの両方を通すこと を確認します。
さっきのコードなら
discount(2000, true); // 割引される
discount(500, true); // 割引されない
これで
if (...) → true
if (...) → false
の両方を通ります。
つまり
- ifの中
- ifの外
どちらも実行されます。
これが C1カバレッジ です。
C2カバレッジ(条件網羅)
C2ではもう少し細かく見ます。
今回の条件は
price > 1000
isMember
の2つです。
それぞれの true / false を確認します。
例えば次のテストです。
discount(2000, true);
discount(2000, false);
discount(500, true);
discount(500, false);
こうすると
| price > 1000 | isMember |
|---|---|
| true | true |
| true | false |
| false | true |
| false | false |
すべての組み合わせを確認できます。
これが C2カバレッジ です。
3つの違い
まとめるとこんな感じです。
| 種類 | 確認すること |
|---|---|
| C0 | コードが実行されたか |
| C1 | 分岐のtrue/false |
| C2 | 条件のtrue/false |
実務ではどこまでやる?
プロジェクトによりますが、よく言われる目安はこんな感じです。
- C0 → 最低限
- C1 → 一般的なテスト
- C2 → 重要ロジックで検討
実際には
- 境界値
- 例外処理
- エラーケース
の方が重要なことも多いです。
カバレッジは「目安」であって、
それだけで品質が決まるわけではありません。
おわりに
テストカバレッジの話は抽象的になりがちですが、
コードで考えると意外とシンプルです。
テストを書くときは
「この条件のtrue / falseは試したか?」
と考えるだけでも、テストの質はかなり変わります。