はじめに
システム開発のユニットテスト実装において、なぜカバレッジ100%を求めてはいけないのか。きちんと自分の中で改めて整理したいという目的で、この記事で共有させて頂こうと思う。
テストコードを書く上で、「カバレッジ100%」という言葉は非常に分かりやすい目標であり、様々な現場で一度は意識されたことがあるものだと思う。
しかし実務を通して感じるのは、カバレッジ100%を“目標”にしてしまうこと自体に落とし穴があるという点である。
なぜカバレッジ100%が問題なのか
次の考え方が自身で1番納得のいく形で整理した考え方である。
「カバレッジ100%を目標にしてしまうと、数字を達成することが目的にすり替わり、本来の目的である"品質担保のためのテスト設計"が置き去りになってしまう」
考えられるアンチパターン
例① テスト漏れ
以下メソッドの UT を実装したい。
public String sample1(int a, int b) {
if (a > b) return "a は b より大きい";
return "a は b より大きくない";
}
以下のような UT を実装した。
@Test
void sample1() {
SampleService targetService = new SampleService();
String actual = targetService.sample1(1, 2);
assertEquals("a は b より大きくない", actual);
}
カバレッジを計測すると100%と判定が出力されるが、明らかに a>b のパターンのテストが実施できていない。
つまり 「カバレッジ100%でも"条件の網羅"は保証されない」
例② 仕様漏れ
以下メソッドの UT を実装したい。
public String sample2(int a, int b) {
if (a > b) {
return "a は b より大きい";
} else {
return "a は b より大きくない";
}
}
以下のような UT を実装した。
@ParameterizedTest(name = "a = {0}, b = {1} のとき {2}")
@CsvSource(delimiter = '|', textBlock = """
# a | b | 期待値
#-----------------------
2 | 1 | a は b より大きい
1 | 2 | a は b より大きくない
""")
void sample2(int a, int b, String expected) {
SampleService targetService = new SampleService();
String actual = targetService.sample2(a, b);
assertEquals(expected, actual);
}
a=b だった場合は「a と b は等しい」を返却する要件を見逃していた。
つまり 「カバレッジは"仕様の正しさ"までは保証しない」
例③ やりすぎ
コードはあえて記載しないが、
- Getter / Setter のテスト
- ToString / equals のテスト
- フレームワークの挙動確認
- ログ出力の検証
- 仕様とは関係ない、本質を捉えていないテスト
- 例②のsample2メソッドで返却される文字列の本質が、文字列の中身ではなく文字数だった場合、本質を捉えられていない品質の低いテストとなる
上記のようなテストに関しては、振る舞いではなく実装に依存している、品質向上への寄与が小さい、という特徴がある。
つまり カバレッジを満たすために「価値の低いテスト」を量産してしまう
なぜ人はカバレッジ100%を目指しがちなのか
これはシンプルで、
- 定量的で分かりやすい
- 達成感がある
- 評価指標にされやすい
- コードレビューしやすい
という理由があるのかなと感じる。
ただし人間の心理として、
目標にした数値を達成するとそれだけで満足してしまう。100%という文字に安心感を覚える。
という性質があると思う。
その結果、
- 本来考えるべきテスト観点を考えなくなる、さぼる
- 「どうテストするか」ではなく「どうカバーするか」を考えるようになる
という本末転倒な状態に陥る。
ではどう向き合うべきか
カバレッジは無意味、と考えているわけではなく、むしろ有用な指標であると感じるが、正しい位置づけが重要だと思う。
良い使い方
- テスト漏れの検知
- 重要ロジックにおける未テスト箇所の可視化
- リファクタリング時の安心材料
悪い使い方
- KPIとして100%を強制する
- PRレビューで「カバレッジ下がってるからNG」
- 数値だけを評価する
さいごに
つまり、テストカバレッジ100%だからといって、
テスト実装の本来の目的である「品質担保」や「不具合の早期検出」を完全に満たしているとは限らない。
カバレッジはあくまで「指標」に過ぎない。
それを目標にしてしまうと、
- 達成して満足する
- 本質を見失う
というリスクがある。
重要なのは、
👉 「何を守りたいのか」から逆算してテストを設計すること
であり、カバレッジはその結果として付いてくるものである。とおもった