SupercovDocumentation

Documentation

MC/DC

Check whether tests exercise each part of a decision independently.

JavaScript

MC/DC stands for Modified Condition/Decision Coverage. It checks whether your tests show each condition in a decision changing the outcome independently.

For a checkout that requires a signed-in customer and an unexpired session, that means testing both requirements. A test that gets through checkout and another that gets rejected can cover both branches while missing the expiry check entirely.

What MC/DC adds to branch coverage

These three cases explain the difference:

CaseSigned in?Session expired?Expected result
A: valid sessionYesNoAllow checkout
B: signed-out visitorNoNoDeny checkout
C: expired sessionYesYesDeny checkout

A and B reach both outcomes. They also show the sign-in requirement changing the result: the expiry input stays the same. But they say nothing about what happens when a signed-in customer’s session expires.

A and C supply that missing comparison. Only the expiry input changes, and checkout goes from allowed to denied. With all three cases, both conditions have an independent check: 2 out of 2, or 100% MC/DC.

Use it with your agent

Supercov measures MC/DC when it runs your tests. Nothing else is needed for this metric. Give your agent the intended behavior as well as the report:

Run the full test suite with npx supercov. Inspect the MC/DC gaps and
add a test for a missing case that matters to this project's behavior.
Only change tests. Rerun the same suite and show the new test, the
decision it checks, and the before-and-after coverage. Explain any
gaps that cannot be tested instead of changing code to raise the score.

Example

Download the example files, extract them, and open the folder for your language. Each folder contains the same checkout rule and two starter tests. Follow the installation guide if Supercov or your language runtime is not installed yet.

The download includes JavaScript, TypeScript, Python, Ruby and Rust examples. For Go, Java and Kotlin selections, this recorded walkthrough shows the JavaScript source and tests; those require Node.js to run.

The source in src/session.js is:

export function checkout(signedIn, expired, price, quantity) {
  if (signedIn && !expired) {
    const total = price * quantity;
    return { status: 'confirmed', total };
  }
  return { status: 'denied', total: 0 };
}

The starter tests check cases A and B. Run them and read the summary:

npx supercov -- npm test
npx supercov runs latest

The recorded coverage section is:

Coverage
  Lines      100.00% (5/5)
  Branches   100.00% (2/2)
  MC/DC      50.00% (1/2)

These are excerpts from Supercov 2.0.0 runs, not estimated results. The source, test command and output follow the language selected above. The download’s README includes instructions for using that exact version.

Find the missing condition

List the gaps, then inspect the decision at its file and line:

npx supercov runs latest gaps --limit 5
npx supercov runs latest decision src/session.js:2

The decision report shows:

cf8decfeb68a3191  src/session.js:2:7
signedIn && !expired
C1 covered: signedIn
C2 MISSING: !expired
confidence executed
vectors:
  F- -> F  tests=1 confidence=executed
  TT -> T  tests=1 confidence=executed
showing 1-2 of 2 conditions/vectors/tests per decision

C2 MISSING is the expiry check. Neither starter test shows an expired session changing the result for a signed-in customer. Case C is the missing test.

The vectors describe execution: T means true, F means false, and - means the condition was not evaluated because an earlier condition short-circuited the decision. A dash is not another false result.

For source context, run:

npx supercov runs latest file src/session.js

Add the test and rerun

Ask your agent to add case C, or replace tests/session.test.js with the completed tests below. The recorded final suite also checks the order total; the expiry test is the change that closes the MC/DC gap.

import assert from 'node:assert/strict';
import test from 'node:test';
import { checkout } from '../src/session.js';

test('confirms an order', () => {
  const order = checkout(true, false, 25, 2);
  assert.equal(order.status, 'confirmed');
  assert.equal(order.total, 50);
});

test('rejects a signed-out visitor', () => {
  const order = checkout(false, false, 25, 2);
  assert.equal(order.status, 'denied');
});

test('rejects an expired session', () => {
  const order = checkout(true, true, 25, 2);
  assert.equal(order.status, 'denied');
});

Run the same command again:

npx supercov -- npm test
npx supercov runs latest

The final coverage section is:

Coverage
  Lines      100.00% (5/5)
  Branches   100.00% (2/2)
  MC/DC      100.00% (2/2)

Line and branch coverage have not changed. The tests now include a case that would fail if checkout stopped rejecting expired sessions.

The complete recordings include both versions of the tests, full reports and assertion-map results. For a separate recorded agent session, see the JavaScript walkthrough. The Vitest and Python comparisons run a similar rule through other coverage tools.

What it doesn’t tell you

100% MC/DC does not mean every input combination was tested. It does not check all numbers, boundary values, event sequences or possible failures. Nor does it establish that the expected result matches your requirements.

Some conditions cannot be varied independently, and some code cannot be fully measured. Read the reported limitations rather than treating an unavailable measurement as a missing test.

MC/DC also does not tell you whether a test checks the returned total or a side effect. Assertion coverage helps you review those links. Mutation testing asks a different question: would a particular change to the code make a test fail?

Read more in the terminal

npx supercov docs coverage-model
npx supercov runs latest decision --help

The installed coverage guide includes MC/DC; there isn’t a separate mcdc topic in the CLI. docs prints the guide, while runs queries your recorded tests. Neither command starts another test run.