ScreenshotNeo

BlogGuides

Code Coverage vs. Test Coverage: What’s the Difference?

Code coverage measures what your tests execute. Test coverage can mean the same thing—or describe a broader set of requirements and behaviors your tests exercise.

By the ScreenshotNeo team4 October 20266 min read

Code coverage measures which parts of your code run when a test suite executes. “Test coverage” is less consistent: some teams use it as another name for code coverage, while others use it for the requirements, behaviors, or other items their tests cover. A percentage is meaningful only when you know what was counted, what code was included, and which tests ran.

Neither term tells you on its own whether the tests would catch a bug. Coverage shows execution; assertions and test selection determine whether important outcomes are checked. [ISTQB Glossary] [Google Testing Blog]

1. What the terms mean

Term What it can mean What to clarify
Code coverage An analysis of which parts of software were executed by a test suite and which were not. Which metric: statements, lines, branches, conditions, functions, or instructions?
Test coverage Sometimes a synonym for code coverage; sometimes coverage of specified requirements, behaviors, risks, or other test items. What is the coverage item, and what counts as exercised?

There is no universal “test coverage percentage” that every tool or team calculates the same way. Google’s discussion uses “code coverage” and “test coverage” interchangeably, while broader testing terminology also describes coverage in terms of specified items. Define the term in your report or team policy rather than assuming the reader knows which meaning you chose. [Google Testing Blog] [ISTQB Glossary]

2. What common code coverage metrics count

Metric What it asks What it can miss
Line coverage Did execution visit each measurable source line? A line containing a decision can run while one outcome remains untested. Tool reporting can map executable code to source lines differently.
Statement coverage Did each executable statement run? Running a decision statement does not necessarily exercise both outcomes.
Branch or decision coverage Did each possible outcome of a decision run? It does not necessarily cover every combination of conditions or every possible execution path.
Condition coverage Did each Boolean condition take its true and false values? It may not prove that every combination of conditions was tested or that the final decision result was checked adequately.
Function or method coverage Was each function or method called? A call can execute without checking its result or exercising its internal alternatives.
Instruction coverage Did each measured instruction execute? Instructions may be counted in compiled output, so the number need not correspond directly to source lines.

Metric names and implementations differ among tools. For example, JaCoCo counts Java bytecode instructions and reports branches for if and switch; its branch counter does not include exception handling. Source mapping can also depend on debug information. [JaCoCo Coverage Counters]

3. Why statement coverage and branch coverage differ

Consider a function with one decision:

function labelFor(balance) {
  if (balance < 0) {
    return "overdrawn";
  }
  return "available";
}

A test that calls labelFor(-1) executes the condition and the first return. It has executed the decision statement, but not the other outcome or the final return. A test that calls labelFor(10) exercises the other outcome. Together, these two cases exercise both branches.

Statement coverage can therefore reach a high value while a decision’s alternative outcome remains unvisited. ISTQB states that 100% branch coverage implies 100% decision and statement coverage; the reverse implication does not follow. This is a relationship among those criteria, not a guarantee that every tool uses identical counting or exclusions. [ISTQB Glossary]

4. What a high percentage does—and does not—tell you

A high code coverage result tells you that the measured code executed during the measured test run. It can help locate unexecuted areas and reveal that a test suite never reaches a feature or error path.

It does not establish that tests checked correct results, that assertions would fail for incorrect behavior, or that the suite covers important inputs and failure conditions. A test can call a function and ignore its return value; that execution may increase coverage without checking the behavior a user depends on. Google’s guidance explicitly warns against treating high coverage by itself as proof that code is well tested. [Google Testing Blog]

Use coverage as a review prompt

  • Inspect uncovered code and ask whether it is important, reachable, and meant to be tested.
  • For covered decisions, confirm that tests exercise meaningful outcomes and boundary cases.
  • Read the assertions: do they check the expected result or merely prevent an exception?
  • For behavior that matters, connect tests to requirements or scenarios so coverage describes more than executed source.
  • Use risk and failure impact to prioritize test work; do not select a target percentage as a substitute for that judgment.

5. How to compare two coverage reports

Two reports that both say “80%” may describe different measurements. Before comparing them, check each of these:

  1. Metric: Is the number line, statement, branch, condition, function, or instruction coverage?
  2. Scope: Which modules, generated files, dependencies, and source sets are included or excluded?
  3. Test run: Did both reports come from the same relevant test suite and runtime conditions?
  4. Tool behavior: Does the tool measure source code or compiled output? How does it handle compiler transformations, source mapping, exclusions, and exceptions?
  5. Meaning of covered: Does execution alone qualify, or is the report tied to requirements or other coverage items?
  6. Test quality: Do tests make meaningful checks of outputs, state changes, and failures?

JaCoCo’s Java counter definitions are one concrete reason to check tool behavior: its instruction counter is based on bytecode, while its branch counter has specific scope and exclusions. GitHub’s coverage reference also describes multiple reported metrics. Compare the definitions and scope, not just the headline percentage. [JaCoCo Coverage Counters] [GitHub Code Coverage Reference]

6. A practical way to report coverage

Make a coverage result interpretable by recording the metric and boundary with the number. For example: “Branch coverage for the application source in the unit-test run, with generated code excluded.” Add the tool and any important exclusions when comparisons or audits depend on them.

  • Keep statement or line and branch results labeled separately.
  • State which source and tests are included.
  • Call broader requirement or behavior coverage by its actual coverage-item name.
  • Review newly uncovered or changed code alongside the report.
  • Pair percentages with test assertions, failure-path review, and risk-based test selection.

A percentage can be useful for tracking a consistently defined measure over time. It becomes misleading when a changed scope, tool, or metric is presented as a directly comparable result without explanation.

7. FAQ

Is test coverage always the same as code coverage?

No. Some sources use the phrases interchangeably; other teams mean coverage of requirements, behaviors, or other specified items by test coverage. Define the term in context.

Does 100% statement coverage mean every branch was tested?

No. A test can execute a decision without taking all its outcomes. Branch coverage asks whether those outcomes were exercised.

Does 100% branch coverage prove the tests are effective?

No. It is evidence about executed branches under a particular metric and scope. It does not establish that assertions would catch incorrect results or that all important requirements were tested.

Why do tools give different percentages for the same project?

They may count different units, analyze source or compiled instructions, apply different exclusions, or run against different code and tests. Check each report’s definitions and scope.

8. Or skip the browser setup

When coverage work includes capturing a rendered page for visual review or a test artifact, ScreenshotNeo provides a website screenshot API and MCP server for developers. Its API returns an image or PDF from one GET request. The coverage percentage itself still comes from your code coverage tool.

For example, save a rendered page as WebP with cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents use screenshot tools. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Create a free account and start with 1,000 screenshots a month, no card required.