Skip to main content
Ai promptsTesting promptsCodingClaude

A Test Coverage Gap Prompt That Finds the Code Your Tests Skip

A reusable test coverage gap prompt that reads source plus tests, ranks untested paths by risk, and returns a locked report. Copy the prompt.

PPromptsCart Team·October 30, 2026·Updated October 30, 2026·8 min read

Coverage reports lie by omission. A file reads 92% line coverage, the dashboard turns green, and everyone moves on. Then a null value slips through an error branch nobody asserted, and the incident channel lights up at 2am. The lines ran. The behavior was never checked.

A test coverage gap prompt attacks the problem line coverage can't see: which behaviors have no test, not which lines executed. You paste the source and the existing tests, and the prompt returns a ranked list of untested paths, each with a reason it matters and a suggested test to close it. It's the analysis step that sits before you generate a single new test.

Most articles on this topic show a one-off Claude Code session, or they're a landing page for a testing platform. Useful, but you can't reuse a screenshot. What follows is the reusable version: the prompt, the output contract, and the model quirks that decide whether the report is trustworthy.

Why line coverage misses the gaps that hurt

Coverage instrumentation records that a statement ran. It says nothing about whether the test asserted the right outcome, or whether the branch ran with the input that actually breaks it. That's the whole trap.

Consider a function with a guard clause for empty input, a happy path, and a catch block. A single test on the happy path can drag the file to 80% coverage. The guard clause never fired. The catch block never fired. The number looks fine. Two behaviors ship untested.

Applitools makes this point directly in its piece on the gaps most teams miss: code coverage and test coverage aren't the same thing, and the gaps that bite live in the space between them. An LLM reading the actual logic can spot those gaps because it reasons about the branches, not the line counter.

Here's the opinionated part. Chasing a coverage percentage is a bad target. Teams that gate merges on "must hit 85%" get tests written to move the number, not to catch defects, and those tests are worse than none because they create false confidence. Rank gaps by risk and fix the top of the list. Ignore the percentage.

What the prompt actually finds

Point it at a module and its tests, and a well-built coverage gap analysis prompt surfaces:

  • Untested branches. Conditionals where one side never runs under any existing test, especially guard clauses and early returns.
  • Unasserted error paths. Catch blocks, thrown exceptions, and rejected promises that execute but check nothing.
  • Boundary values. Off-by-one edges, empty collections, zero, negative numbers, and max-length inputs the happy-path tests skip.
  • Null and undefined handling. Every parameter that could arrive missing and isn't defended.
  • State-dependent paths. Behavior that only triggers after a specific prior call or a particular object state.
  • Concurrency and ordering. Where two operations racing could produce a result no test pins down.

Each of those is a behavior, not a line. That's the distinction the report is built on.

Anatomy of the coverage gap prompt

The shape that holds up across models puts the role first, the inputs in labeled fences, and the output contract dead last so the model weights it on long pastes:

Role: You are a test coverage analyst. You find untested BEHAVIOR,
not uncovered lines.

Source under review:
"""
{{source_code}}
"""

Existing tests:
"""
{{existing_tests}}
"""

Focus areas (optional): {{focus_areas}}

Task:
1. Map every branch, error path, and boundary in the source.
2. For each, decide if an existing test asserts its outcome.
3. Report only the UNTESTED ones, ranked by risk.

Output contract (return exactly this, no preamble):
| Risk | Untested path | Why it matters | Suggested test name |
Risk is one of: high, medium, low.
If a value is not determinable from the code, write "Not stated".
Return no prose outside the table.

The {{source_code}} and {{existing_tests}} variables are the two artifacts you already have open. No prep work, no describing your architecture in prose first. Paste and run.

Why the contract goes last

Models weight recent tokens more heavily. On a long paste, an instruction at the top gets diluted by everything after it. Put the output contract below the code and the model honors the table shape far more reliably. This isn't folklore; it's the same reason a "respond in JSON" note at the top of a 4,000-token prompt gets ignored while the same note on the final line sticks.

Model behavior: Claude vs ChatGPT vs Cursor

The report is only as good as the model's discipline about staying inside the contract. They don't behave the same.

ModelBranch reasoningContract adherenceWatch for
Claude (Sonnet/Opus)Strong; traces guard clauses and catch blocks wellHonors a table contract reliably, especially when it's the last blockOccasionally over-reports low-risk gaps; cap the list
GPT-4o / GPT-5Good; fast, sometimes skims deeper nestingNeeds the "no prose outside the table" line restated at the endWill add a helpful intro paragraph unless told not to
Cursor (agent mode)Reads the whole repo, so it catches cross-file gapsLooser on format; it wants to write the tests, not list themGreat for fixing gaps, noisier for the analysis-only pass

The practical read: use Claude or GPT for the analysis pass because you want a clean ranked list, then hand the top gaps to Cursor or Claude Code to actually write the tests. Cursor is a poor listing tool and a great fixing tool. Don't make it do both in one shot.

One more quirk worth knowing. A DEV Community walkthrough of a Claude Code coverage workflow generates two dozen test cases in a run but never ranks them. That's the missing half. Without a risk tier you get a wall of equally-weighted suggestions, and you're back to guessing which ones matter.

Variables you'll set

VariableRequiredWhat it is
{{source_code}}YesThe module, class, or file under review, pasted verbatim
{{existing_tests}}YesThe current test file(s) for that source
{{focus_areas}}NoOptional narrowing, e.g. "error handling and auth"

Keep each run scoped to one module plus its tests. Paste an entire service and the model spreads its attention thin and misses the deep branches. Smaller inputs, sharper gaps.

Getting started

  1. Pick one file that matters and open its test file next to it.
  2. Paste both into {{source_code}} and {{existing_tests}}.
  3. Leave {{focus_areas}} empty for the first pass to see everything.
  4. Run on Claude or GPT and read the high-risk rows first.
  5. Rerun with {{focus_areas}} set to the theme you care about (auth, error handling) for a deeper cut.
  6. Hand the top three rows to your coding agent to write the tests.
  7. Skip the low-risk rows unless you're bored. The point is risk, not the number.

For the analysis-plus-fix loop end to end, the Test Coverage Gap Harness packages the ranked-report prompt with companion prompts that turn each gap into a test. It's the difference between a one-off session and a repeatable pass you run every PR.

Skip the setup

The Test Coverage Gap Harness does this end-to-end: a {{source_code}} and {{existing_tests}} pair feeds a locked risk-ranked table, and a bundled companion prompt drafts the missing test for any row you pick. It's part of The Complete AI Prompts Bundle, a one-time lifetime license to the whole catalog plus every pack added later, worth it if you run more than one of these engineering jobs.

Get the Test Coverage Gap Harness →

A caveat before you trust any of this: models hallucinate paths that don't exist, especially on unfamiliar frameworks. Read each suggested test against the real code before you write it. The prompt narrows where to look. It doesn't replace looking.

Coverage gap analysis pairs naturally with two other jobs. If you're generating the tests themselves, the generate unit tests with AI prompt takes the gap and writes the assertion. And when a test starts failing intermittently after you add it, the flaky test detection prompt tells you whether it's the test or the code. Browse the full set of engineering prompts in the catalog when you're ready to wire coverage analysis into your review flow.

Browse the prompt catalog →
FAQ

Common questions

What is a test coverage gap prompt?
It's a reusable AI prompt that reads your source code and existing tests, then reports which branches, error paths, and edge cases have no test, ranked by risk. Unlike a coverage tool that reports line percentages, it names the specific untested behavior and why it matters.
Isn't line coverage enough to find gaps?
No. Line coverage tells you a line ran during a test, not that the behavior was asserted. A file can show 90% line coverage while every error branch, boundary value, and null path goes unchecked. A gap prompt reasons about behavior, not executed lines.
Can ChatGPT or Claude do this without a prompt pack?
They can attempt it, but output drifts run to run without a locked contract. A structured prompt fixes the report shape: a risk tier, the untested path, a reason, and a suggested test name for each gap, so the same input yields the same shape every time.
Stop reading. Start shipping.

Get the prompt packs this guide is built on

Ready-to-paste prompts with documented variables and usage guides for ChatGPT, Claude, and Gemini. One-time payment, own it forever.