# MC/DC vs branch coverage > Branch coverage asks whether a decision went both ways. MC/DC asks whether each condition changed the result on its own. One example in four languages. Web page: https://supercov.com/compare/mcdc-vs-branch-coverage · Published 2026-10-12 All Supercov pages for agents: https://supercov.com/llms.txt · Full text: https://supercov.com/llms-full.txt ## What is the difference? Branch coverage asks whether each decision went both ways. MC/DC asks whether each condition inside the decision was shown, on its own, to change the result. For a decision with one condition they need the same tests. They differ when a decision joins conditions with `&&` or `||`. ## One line, two answers ```js if (signedIn && !expired) { return true; } return false; ``` Two tests: a signed-in session that is not expired gets `true`, and a signed-out session gets `false`. The `if` went both ways, so branch coverage is 100%. The two tests also show that `signedIn` matters: it is the only input that changed, and the result flipped. Nothing shows that `expired` matters. Delete `&& !expired` and both tests still pass. MC/DC is 1 of 2 conditions. A third test, signed in and expired, completes it. ## How the criteria compare | Criterion | Question | Tests for `a && b && c` | | --- | --- | --- | | Line or statement | Did it run? | 1 | | Branch (decision) | Did the decision go both ways? | 2 | | MC/DC | Did each condition change the result on its own? | 4 | | Multiple condition | Was every combination tried? | 8 | MC/DC needs at least one more test than there are conditions. Trying every combination doubles with each condition added. MC/DC comes from avionics, where DO-178C requires it for the most critical software. ## What tools report for that line We ran the same check and the same two tests in four languages: | Tool | Result for the decision | | --- | --- | | Jest 30.5.2, Babel provider | 4/4 branches | | coverage.py 7.16.2 | 2/2 branches | | `go test -cover`, Go 1.27.1 | 100% of statements; no branch metric | | JaCoCo 0.8.15 | 3/4 branches | | Supercov 4.3.0, all four | branches covered; `!expired` not shown | JaCoCo comes closest because it counts bytecode: `javac` compiles `&&` into one conditional jump per condition, and the expired side of the second jump was never taken. That finds this gap. It still shows that each jump happened, not that a condition changed the result on its own. ## Which one to use Branch coverage is enough for code whose decisions are single conditions. Use MC/DC where decisions combine conditions: access checks, pricing rules, feature flags, validation. Use it where a standard asks for it. ## Measure MC/DC on your tests ```sh npx supercov -- npm test npx supercov runs latest gaps ``` Supercov runs your existing test command and measures line, branch and MC/DC coverage for JavaScript, TypeScript, Python, Go, Java, Kotlin, Rust and Ruby. For each gap it names the condition and the missing case. The [MC/DC guide](https://supercov.com/docs/mcdc.md) walks through an example. New to the simpler metrics? See [line coverage vs branch coverage](https://supercov.com/compare/line-vs-branch-coverage.md). Example evidence: [fixture source, commands and recorded results (JSON)](https://supercov.com/downloads/tool-comparisons-2026-10-12.json). Measured October 12, 2026 with Supercov 4.3.0. These small examples are not a performance benchmark or a general conformance test.