【コード解説付き】C0/C1/C2/MCCカバレッジとは?分岐網羅・条件網羅の違い

ソフトウェアテストをしていると必ず出てくる疑問があります。
どこまでテストをすれば十分なのか?
その指標のひとつが テストカバレッジ(Test Coverage) です。
この記事では、テスト現場で特に重要な 4 つの指標
C0(命令網羅) / C1(分岐網羅) / C2(条件網羅) / MCC(複合条件網羅)
を、じゃんけん判定コードの実例を交えて解説します。あわせて、カバレッジの測定ツール・目標値の決め方・現場での使い分けまで整理します。

テストカバレッジとは?
テストカバレッジとは、テスト対象のうちどれだけをテストできたかを数値で示す指標です。日本語では「網羅率」とも呼ばれます。
「テストは十分やりました」という報告は主観的で、受け手によって解釈が変わります。カバレッジを使うと、この曖昧さを「分岐網羅率 85%」のように共通の物差しに置き換えられるようになります。
コードカバレッジと、それ以外のカバレッジ
「カバレッジ」と呼ばれるものは 1 種類ではありません。何を分母に置くかで種類が分かれます。
- コードカバレッジ:ソースコードを分母にする。C0 / C1 / C2 / MCC はすべてこれに属する
- 機能カバレッジ:仕様書に書かれた機能を分母にする
- 要求カバレッジ:要件定義書の要求項目を分母にする
- 業務シナリオカバレッジ:実際の業務フローを分母にする
C0〜MCC は単体テスト(ユニットテスト)で使うコードカバレッジです。結合テストやシステムテストの十分性は、コードカバレッジでは測れません。この記事では主にコードカバレッジを扱い、最後にそれ以外のカバレッジとの関係を整理します。
C0 / C1 / C2 / MCC 早見表
先に全体像を示します。詳細はこの後、コードを使って 1 つずつ解説します。
| 指標 | 日本語名 | 英語名 | 何を網羅するか |
|---|---|---|---|
| C0 | 命令網羅 | Statement Coverage | すべての実行文を 1 回以上通す |
| C1 | 分岐網羅 | Branch / Decision Coverage | すべての分岐で true と false の両方を通す |
| C2 | 条件網羅 | Condition Coverage | 個々の条件が True と False の両方になる |
| MCC | 複合条件網羅 | Multiple Condition Coverage | 条件の組み合わせをすべて通す |
じゃんけん判定コードを例にカバレッジを理解する
ここでは、サンプルコードを使って「どの部分がどのカバレッジに関係するのか」を理解していきます。コードの流れを把握しておくと、C0〜MCC の違いが一気に分かりやすくなります。
function janken($player1, $player2) {
$validHands = ['rock', 'paper', 'scissors'];
if (!in_array($player1, $validHands) || !in_array($player2, $validHands)) {
return 'invalid';
}
if ($player1 === $player2) {
return 'draw';
}
if (
($player1 === 'rock' && $player2 === 'scissors') ||
($player1 === 'scissors' && $player2 === 'paper') ||
($player1 === 'paper' && $player2 === 'rock')
) {
return 'player1_wins';
}
return 'player2_wins';
}
コードの判定パターン(4種類)
invalid: 不正入力(手が rock/paper/scissors でない)draw: 引き分け(手が同じ)player1_wins: プレイヤー1の勝ちplayer2_wins: プレイヤー2の勝ち
この 4 種類の結果が、カバレッジ設計の中心になります。
C0(命令網羅 / Statement Coverage)とは?
C0 カバレッジは、最も基本的でシンプルなカバレッジ指標です。
まずはここを理解することで「カバレッジの考え方」に慣れることができます。
C0 の定義
C0 は コード内のすべての命令(実行文)を少なくとも 1 回実行する という基準です。
ポイントは、数えるのは「実行された文」であって「通った分岐」ではないという点です。if 文の条件式が評価されれば、その if 行自体は実行済みとしてカウントされます。ただし if のブロック内にある文は、実際に中へ入らなければ実行されません。
1 ケースでは C0 を達成できない
ここが最初のつまずきポイントです。次の 1 ケースだけを実行したとします。
janken('rock', 'scissors'); // 結果: player1_winsこのとき、実行された文と実行されなかった文は次のようになります。
- ✅
$validHands = [...]:実行された - ✅ 3 つの
ifの条件式:すべて評価された - ✅
return 'player1_wins';:実行された - ❌
return 'invalid';:未実行 - ❌
return 'draw';:未実行 - ❌
return 'player2_wins';:未実行
4 つある return のうち 1 つしか実行されていないため、C0 は未達成です。
「C0 は 1 ケースで達成できる」と説明されることがありますが、それが成り立つのは return や throw による途中終了がないコードに限られます。実務のコードは早期リターンを多用するため、この前提はほとんど成り立ちません。
このコードで C0 を達成するには 4 ケース必要
4 つの return をすべて実行する必要があるため、最低 4 ケースになります。
janken('invalid', 'rock'); // return 'invalid' を実行
janken('rock', 'rock'); // return 'draw' を実行
janken('rock', 'scissors'); // return 'player1_wins' を実行
janken('rock', 'paper'); // return 'player2_wins' を実行C0 の本質(ここが超重要)
C0 = すべての実行文を一度でも通すこと。
早期リターンのあるコードでは、C0 の達成に必要なケース数は C1 とほぼ同じになる。
C0 は簡単に達成できそうに見えて、実は「early return(途中 return)」によって未実行の命令が残りやすいのが難点です。C0 が 100% でないコードは、そもそもテストされていない処理が残っているということなので、最低ラインとして必ず確認しましょう。
C1(分岐網羅 / Branch・Decision Coverage)とは?
C1 は、現場で最もよく利用されるカバレッジ基準です。
「この程度は最低やっておきたい」という、多くのプロジェクトの標準ラインです。デシジョンカバレッジ(判定条件網羅)と呼ばれることもあります。
C1 の定義
C1 は すべての分岐(if 文)で true と false の両方を通す 必要があります。
C0 と違って、「条件式が最終的にどちらに転んだか」まで確認する必要があります。
C1 は最小 4 ケースで達成可能
4 つの結果すべてを最低 1 回ずつ通す必要があります。
- invalid
- draw
- player1_wins
- player2_wins
例:C1 を満たす 4 ケース
janken('invalid', 'rock'); // if1: true
janken('rock', 'rock'); // if1: false / if2: true
janken('rock', 'scissors'); // if2: false / if3: true
janken('rock', 'paper'); // if3: falseこれにより、全ての if が true も false も通ります。このコードでは C0 と C1 が同じ 4 ケースで達成されますが、これは早期リターンが多いコード特有の性質です。if の中に複数行の処理があるコードでは、C0 のほうが少ないケース数で達成できます。
C1 の弱点:複雑な条件の内部は網羅できない
player1 勝利条件には 3 種類ありますが、C1 では 1 種類通れば OK になります。
- rock → scissors
- scissors → paper
- paper → rock
つまり scissors → paper の判定にバグがあっても、C1 100% のまま見逃されます。「内部の条件までは検証できない」というのが C1 の限界です。ここを埋めるのが次の C2 です。
C2(条件網羅 / Condition Coverage)とは?
C2 は、|| や && で結ばれた個々の条件に着目するカバレッジです。C1 と組み合わせて使うことが推奨されます。
C2 の定義
C2 は すべての条件式について、各条件が少なくとも 1 回 True と 1 回 False になるようにテスト します。
複合条件(OR や AND)を持つ if がある場合、その個々の条件の真偽をテストしますが、すべての組み合わせをテストする必要はありません。
重要: C2 と複合条件網羅(MCC)は異なります。C2 は各条件が True/False になることを確認しますが、すべての組み合わせは不要です。
C2 を満たすテストケース
じゃんけんの例で条件を数えると、if1 が 2 条件、if2 が 1 条件、if3 が 3 条件で、合計 6 条件あります。それぞれを True と False の両方にする必要があるため、最小 7 ケース必要になります。
// 【if1: 入力チェック】2条件
janken('invalid', 'rock'); // 第1条件 True
janken('rock', 'invalid'); // 第1条件 False / 第2条件 True
janken('rock', 'scissors'); // 第1条件 False / 第2条件 False
// 【if2: 引き分けチェック】1条件
janken('rock', 'rock'); // 条件 True(False は上のケースで充足)
// 【if3: プレイヤー1勝利チェック】3条件
janken('rock', 'scissors'); // 第1条件 True
janken('scissors', 'paper'); // 第2条件 True
janken('paper', 'rock'); // 第3条件 True
janken('rock', 'paper'); // 3条件すべて Falsejanken('rock', 'scissors') が if1 と if3 の両方で使えるため、ユニークなケース数は 7 になります。
見落としがちな落とし穴:短絡評価(ショートサーキット)
PHP・Java・JavaScript などの || と && は短絡評価されます。左側だけで結果が確定すると、右側の条件はそもそも評価されません。
上の例で janken('invalid', 'rock') を実行すると、if1 の第1条件が True になった時点で第2条件は評価されずに終わります。
「条件を書いたのに一度も評価されていない」という状態が起こりうる。
C2 のテストケースを設計するときは、狙った条件が本当に評価される順序になっているかを確認する必要があります。
これはカバレッジ計測ツールの数値が想定と食い違う代表的な原因でもあります。
C2 の重要な注意点
C2 だけでは C1 を満たさない場合があります。
例えば、if (A || B) という条件で以下のテストをした場合:
- (A=True, B=False) → 全体は True
- (A=False, B=True) → 全体は True
この場合、A と B は両方 True/False を経験していますが(C2 達成)、if 文全体が False になるケースがテストされていません(C1 未達成)。
実務では「C1/C2 カバレッジ」として両方を満たすことが推奨されます。
MCC(複合条件網羅 / Multiple Condition Coverage)とは?
MCC は、もっとも厳密で「テスト漏れを極限まで減らす」カバレッジです。
MCC の定義
MCC(Multiple Condition Coverage)は 条件式に含まれるすべての条件の組み合わせを網羅 します。
複合条件(OR や AND)を持つ if がある場合、その内部の真偽パターンをすべて確認しなければなりません。
C2 との違い:
- C2:各条件が少なくとも 1 回 True/False(組み合わせは不要)
- MCC:すべての条件の組み合わせをテスト
MCC が重い理由:組み合わせが指数的に増える
条件が n 個あれば、組み合わせは 2 の n 乗になります。じゃんけんの例では次のとおりです。
| 分岐 | 条件数 | 論理的な組み合わせ | 実際に到達可能 |
|---|---|---|---|
| if1(入力チェック) | 2 | 4 通り | 4 通り |
| if2(引き分け) | 1 | 2 通り | 2 通り |
| if3(player1 勝利) | 3 | 8 通り | 4 通り |
if3 が 8 通りではなく 4 通りなのは、3 つの条件が同時に True になることがありえないためです。「グーがチョキに勝つ」と「チョキがパーに勝つ」は同じ 1 回のじゃんけんでは両立しません。
MCC の組み合わせには「論理的には存在するが、実際には到達できない」パターンが含まれる。
到達不能な組み合わせを無理に作ろうとすると、テストケース設計が破綻します。
到達可能な組み合わせを網羅すると、次の 12 ケースになります。
// 【入力チェック】3ケース
janken('invalid', 'invalid'); // 両方無効
janken('invalid', 'rock'); // player1無効
janken('rock', 'invalid'); // player2無効
// 【引き分け】3ケース
janken('rock', 'rock'); // グー同士
janken('paper', 'paper'); // パー同士
janken('scissors', 'scissors');// チョキ同士
// 【プレイヤー1勝利】3ケース
janken('rock', 'scissors'); // グー > チョキ
janken('scissors', 'paper'); // チョキ > パー
janken('paper', 'rock'); // パー > グー
// 【プレイヤー2勝利】3ケース
janken('rock', 'paper'); // パー > グー
janken('paper', 'scissors'); // チョキ > パー
janken('scissors', 'rock'); // グー > チョキ複雑なロジックほど組み合わせが増え、テストコストが重くなるのが MCC の特徴です。条件が 5 個あれば 32 通り、10 個あれば 1,024 通りになるため、コード全体に適用するのは非現実的です。
C0 / C1 / C2 / MCC の違いをまとめて理解する
カバレッジ指標は、網羅性とコストのバランスで選ぶ必要があります。必要ケース数は、この記事のじゃんけんコードを対象にした場合の数値です。
| カバレッジ | 内容 | 必要ケース数 | 特徴 | 実務での用途 |
|---|---|---|---|---|
| C0 | すべての実行文を 1 回以上通す | 4 | 最小・簡単 | 動作確認、最低限の品質保証 |
| C1 | すべての分岐で true/false を通す | 4 | バランス良 | ほぼ標準的な品質確保 |
| C2 | 各条件が少なくとも1回True/False | 7 | 個々の条件に着目 | 複雑な条件式の検証(C1と組み合わせ推奨) |
| MCC | 条件の全組み合わせを通す | 12 | もっとも厳密 | 金額計算、権限ロジック、セキュリティ系 |
網羅性の強さは C0 < C1 < MCC の順です。C2 は C1 とは別の軸を見ているため、単純な上下関係にはなりません(C2 を満たしても C1 を満たさないケースがあるのは前述のとおりです)。
カバレッジの測定方法とツール
カバレッジは手作業で数えるものではなく、計測ツールを単体テストと一緒に実行して自動で算出します。主要言語のツールは次のとおりです。
| 言語 | 代表的なツール | 測定できる主な指標 |
|---|---|---|
| Java | JaCoCo | C0 / C1 |
| PHP | Xdebug + PHPUnit | C0 / C1 |
| JavaScript / TypeScript | Istanbul(nyc)、Vitest | C0 / C1 / 関数・行カバレッジ |
| Python | coverage.py、pytest-cov | C0 / C1 |
| C / C++ | gcov、lcov | C0 / C1 |
| C# | Coverlet、dotCover | C0 / C1 |
ツールの用語に注意
多くのツールは C0 を「Statement(行)カバレッジ」、C1 を「Branch カバレッジ」と表記します。「C0/C1」という呼び方は日本の開発現場で広く使われる一方、ツールのレポート画面には出てこないことがほとんどです。
また、C2 や MCC を標準で測定できるツールは多くありません。これらは計測ツールに頼らず、テスト設計の段階で意図的にケースを起こす必要があります。
CI に組み込んで初めて機能する
カバレッジは一度測って終わりにすると形骸化します。GitHub Actions や Jenkins などの CI に組み込み、「カバレッジが基準値を下回ったらマージできない」仕組みにすることで、はじめて品質の歯止めとして働きます。
カバレッジ目標値の決め方
なぜ 100% を目指さないのか
カバレッジ 100% は理想的に見えますが、実務では推奨されないことが多くあります。理由は 3 つです。
- コストが急激に増える:80% から 100% に上げる労力は、0% から 80% に上げる労力を上回ることが珍しくありません
- 到達不能なコードがある:例外処理や防御的なコードには、通常の実行では到達できない箇所が含まれます
- 数値を満たすためのテストが生まれる:アサーションのない「実行するだけのテスト」でも、カバレッジは上がってしまいます
リスクに応じて目標値を変える
全体で一律の数値を設定するのではなく、コードの重要度で目標値を分けるのが現実的です。
| 対象 | 目安となる C1 目標 | 考え方 |
|---|---|---|
| 金額計算・権限判定・セキュリティ | 100%(+ MCC) | 不具合の損害が大きい |
| 主要な業務ロジック | 80〜90% | 標準ライン |
| 画面表示・単純な CRUD | 60〜70% | 結合テストで補える |
| 自動生成コード・設定ファイル | 測定対象外 | テストする価値が低い |
重要なのは数値そのものより、下がったときに気づける状態を保つことです。前回 85% だったものが 70% に落ちたなら、テストのないコードが追加されたというシグナルになります。
実務でのカバレッジ設計のおすすめ
現場では、以下のような基準で使い分けるのが現実的です。
① 基本は C1(80%)を目指す
C1 は実務で最も妥当なライン。
無駄なテストを増やさずにメリハリのあるテストができます。
② 複雑な条件式は C2 も組み合わせる
複雑な OR/AND 条件がある場合、C1 だけでは個々の条件の動作が確認できません。
C1/C2 カバレッジとして両方を満たすことで、より高い品質を確保できます。
③ 重要ロジックは MCC を適用
不具合の影響が大きい箇所は MCC を適用する価値があります。
- 売上計算
- 課金ロジック
- ログイン判定
- 権限チェック
など
④ 時間がない場合や低リスク箇所は C0
最低限の動作保証だけで十分な場合は C0 で済ませるという判断も適切です。ただし C0 が 100% でない場合は「一度も実行されていない処理がある」ことを意味するため、そこだけは確認しておきましょう。
⑤ カバレッジだけでは品質保証できない
カバレッジは「通ったかどうか」しか見ておらず、「結果が正しいか」は評価していません。アサーションを書かないテストでもカバレッジは 100% になります。以下も欠かせません。
- 境界値分析
- 異常系テスト
- 性能テスト
- 統合テスト
単体テスト以外のカバレッジ
C0〜MCC はコードを分母にした指標のため、結合テスト以降の十分性は測れません。工程が進むにつれて、分母は次のように変わります。
| 工程 | 使うカバレッジ | 分母になるもの |
|---|---|---|
| 単体テスト | C0 / C1 / C2 / MCC | ソースコード |
| 結合テスト | インターフェースカバレッジ | モジュール間の連携経路 |
| システムテスト | 機能カバレッジ / 要求カバレッジ | 仕様書の機能・要求項目 |
| 受入テスト | 業務シナリオカバレッジ | 実際の業務フロー |
C1 が 90% でも、仕様書の機能を半分しかテストしていなければ品質は担保できません。コードカバレッジはあくまで単体テストの十分性を測る道具であり、工程ごとに適切な分母を選ぶことが重要です。
よくある質問
C1 と C2 はどちらを優先すべきですか?
まず C1 です。C1 は分岐の結果を網羅する基本の指標で、多くの計測ツールが標準で対応しています。C2 は || や && を含む複雑な条件式がある箇所に絞って追加するのが効率的です。
カバレッジ 100% ならバグはないと言えますか?
言えません。カバレッジは「コードが実行されたか」を測る指標で、「結果が正しいか」は見ていません。また、実装されていない仕様の漏れはカバレッジには一切現れません。
C0 と C1 で必要なケース数が同じになることはありますか?
あります。この記事のじゃんけんコードがまさにその例で、早期リターンが多いコードでは C0 と C1 の必要ケース数が一致しやすくなります。
C2 と MCC の違いが分かりません
if (A || B) を例にすると、C2 は「A が True/False の両方、B が True/False の両方」を経験すれば達成です(2 ケースで足ります)。MCC は「(A,B) = (T,T)(T,F)(F,T)(F,F)」の 4 通りすべてが必要です。資料によっては C2 を MCC の意味で使っている場合もあるため、チーム内で定義を揃えておくことが重要です。
分岐網羅と判定条件網羅は違うものですか?
同じものを指します。C1 は「分岐網羅」「ブランチカバレッジ」「デシジョンカバレッジ」「判定条件網羅」など複数の呼び方があります。
まとめ
- C0 は「すべての実行文を通すこと」。早期リターンがあると 1 ケースでは達成できない
- C1 は「実務で最もバランスが良い基準」。まずはここを 80% 目標に
- C2 は「個々の条件に着目するが、C1 と組み合わせて使うべき」
- MCC は「重要なロジックに適用すると効果大」だがコストも高い
- 短絡評価により「書いたのに評価されない条件」が生まれる点に注意
カバレッジは万能ではありませんが、テストの”漏れを可視化”する大事な指標です。
プロジェクトのリスクや予算に応じて、C0〜MCC をうまく使い分けることが品質向上の近道です。
重要:C2 と MCC を混同しないこと
C2 は「各条件が True/False を経験する」、MCC は「すべての組み合わせをテスト」という明確な違いがあります。資料によっては C2 を MCC の意味で使っている場合もあるため、着手前に定義を確認しておきましょう。

カバレッジ目標を決めても、そこまで測る人手が足りないときは
「C1 で 80%」のような目標を立てても、そこへ到達するテストケースを書き、CI に組み込み、未到達の分岐を潰していく作業には工数がかかります。次のような状況であれば、テスト工程だけを切り出す選択肢もあります。
- カバレッジを測る仕組みはあるが、未到達箇所を埋める時間がない
- 目標値は決めたものの、実際の測定・報告まで手が回っていない
- 重要ロジックだけでも第三者にテストしてほしい
みんなシステムズのテスト代行は、受託開発の現場でシステムを作ってきた現役エンジニアが担当します。10万円から、テストだけを切り出してお任せいただけます。


次に読むならこの記事
テストの手戻りを減らしたい方へ
テスト仕様書のExcelテンプレートを無料で配布しています。自社で整備する場合も、外部に任せる場合も、まずは型を持つところから。


