# MC/DC coverage for JavaScript > See how MC/DC finds an untested condition in JavaScript, even with 100% line and branch coverage. A small example with real Supercov output. Web page: https://supercov.com/blog/mcdc-coverage-javascript · Published 2026-09-09, updated 2026-09-13 All Supercov pages for agents: https://supercov.com/llms.txt · Full text: https://supercov.com/llms-full.txt Line and branch coverage can reach 100% while a condition goes untested. MC/DC shows what’s missing. A checkout function can have 100% line and branch coverage without a test for an expired session. Both return paths run. Both tests pass. But removing the expiry check still leaves the suite green. MC/DC coverage asks a more specific question: has each condition been shown to change the decision on its own? Here's what that looks like in JavaScript, using a small example we ran with Supercov. ## The condition the tests miss This function allows checkout when a customer is signed in and their session has not expired: ```js export function canCheckout(signedIn, expired) { if (signedIn && !expired) return true; return false; } ``` The original tests check a valid session and a signed-out visitor: ```js assert.equal(canCheckout(true, false), true); assert.equal(canCheckout(false, false), false); ``` One test takes the `true` return path. The other takes the `false` path. Neither passes `true` for `expired`. If we accidentally change the condition to just `signedIn`, both tests still pass. An expired session would now be accepted. ![signedIn true and expired true produce canCheckout false.](https://supercov.com/assets/expired-session-v2-1360.41e865d2a9.webp) *The missing case: a signed-in visitor with an expired session cannot check out.* ## What MC/DC measures MC/DC stands for **Modified Condition/Decision Coverage**. A decision is the whole expression, `signedIn && !expired`. Its two conditions are `signedIn` and `!expired`. For each condition, MC/DC looks for a pair of executions showing that the condition independently changes the decision's outcome. For this example, the useful cases are: | Case | `signedIn` | `expired` | Checkout allowed? | | --- | --- | --- | --- | | Valid session | `true` | `false` | `true` | | Signed out | `false` | `false` | `false` | | Expired session | `true` | `true` | `false` | Compare the first two rows: changing `signedIn` changes the result. Compare the first and third: changing `expired` changes the result while `signedIn` stays true. The original suite has the first pair, but not the second. JavaScript short-circuits `&&`: when `signedIn` is false, it does not evaluate `!expired`. Coverage tools need to retain that distinction rather than treating a skipped condition as a false one. The precise witness rules also depend on the form of MC/DC being measured; [Clang's coverage documentation](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#mc-dc-instrumentation) explains its masking approach. For this small example, the missing expired-session case is straightforward. ## Measure it with Supercov Run your existing test command through Supercov, then query the result: ```sh npx supercov -- npm test npx supercov runs latest ``` Everything after `--` is your project's test command. Here, `npm test` runs the example's two tests. This is the coverage summary from that recorded run: ```text Coverage Lines 100.00% (3/3) Branches 100.00% (2/2) MC/DC 50.00% (1/2) ``` These are Supercov's counts for this file, not a claim that every coverage provider would print the same percentages. Different tools count branches differently. In particular, ordinary branch or condition counters are not the same as evidence that a condition independently changes a decision. To see what's missing: ```sh npx supercov runs latest gaps npx supercov runs latest file src/session.js ``` The file view identifies the condition: ```text LINE STATUS SOURCE 2 PARTIAL signedIn && !expired Unobserved: no witness pair shows `!expired` independently changing the decision result ``` That is enough information to choose a test. We need a signed-in customer whose session has expired. ## Add a test that checks the missing behavior In our recorded run, the coding agent added this test and left the application code unchanged: ```js test('a signed-in visitor with an expired session cannot check out', () => { assert.equal(canCheckout(true, true), false); }); ``` The assertion matters. Calling the function would exercise the condition; checking the result verifies that this input is denied checkout. After rerunning the same suite, all three tests passed. The agent compared the new run with the baseline: ```sh npx supercov -- npm test npx supercov diff latest ``` Replace `` with the ID from your baseline run. The recorded comparison showed: ```text lines +0pp, branches +0pp, MC/DC +50pp gained: 0 lines, 0 branches, 1 MC/DC conditions lost: 0 lines, 0 branches, 0 MC/DC conditions + MC/DC src/session.js:2 C2 !expired ``` Line and branch coverage did not change. The suite now checks a behavior it did not check before. Removing the expiry guard makes the new test fail. ![MC/DC coverage increases from 50% to 100%.](https://supercov.com/assets/mcdc-coverage-gain-v2-1360.ac26a06d46.webp) *One additional test takes MC/DC from 50% to 100%. Line and branch coverage stay at 100%.* You can [download the original two-test project](https://supercov.com/downloads/supercov-tutorial.zip) or inspect the [source files and recorded run](https://github.com/supercorp-ai/supercov/tree/main/examples/checkout-verification). The [Agent workflow guide](https://supercov.com/docs/agent-loop.md#example) walks through reproducing it with your own agent. ## Use it with a coding agent You don't need to pick every gap yourself. Open your project in your agent and ask: ```text Measure code coverage with npx supercov and write one missing test. Only change tests. Rerun the full test suite and show me the test you added and the before-and-after coverage. ``` Supercov supplies the measurements. The agent runs the commands and writes the test. Review the changed test and the comparison in the conversation. MC/DC is useful for conditions in session checks, permissions, discounts, and feature gates. It does not establish that the requirement itself is right, that every input is tested, or that the program is bug-free. Use it to find specific gaps, then write assertions for the behavior you actually want. For runner and language requirements, see [Supported languages](https://supercov.com/docs/supported-suites.md). For the meaning and limits of each metric, see [Understanding coverage](https://supercov.com/docs/coverage-model.md).