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.
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.
| Model | Branch reasoning | Contract adherence | Watch for |
|---|---|---|---|
| Claude (Sonnet/Opus) | Strong; traces guard clauses and catch blocks well | Honors a table contract reliably, especially when it's the last block | Occasionally over-reports low-risk gaps; cap the list |
| GPT-4o / GPT-5 | Good; fast, sometimes skims deeper nesting | Needs the "no prose outside the table" line restated at the end | Will add a helpful intro paragraph unless told not to |
| Cursor (agent mode) | Reads the whole repo, so it catches cross-file gaps | Looser on format; it wants to write the tests, not list them | Great 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
| Variable | Required | What it is |
|---|---|---|
{{source_code}} | Yes | The module, class, or file under review, pasted verbatim |
{{existing_tests}} | Yes | The current test file(s) for that source |
{{focus_areas}} | No | Optional 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
- Pick one file that matters and open its test file next to it.
- Paste both into
{{source_code}}and{{existing_tests}}. - Leave
{{focus_areas}}empty for the first pass to see everything. - Run on Claude or GPT and read the high-risk rows first.
- Rerun with
{{focus_areas}}set to the theme you care about (auth, error handling) for a deeper cut. - Hand the top three rows to your coding agent to write the tests.
- 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.
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.
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 →Common questions
What is a test coverage gap prompt?
Isn't line coverage enough to find gaps?
Can ChatGPT or Claude do this without a prompt pack?
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.
More prompt guides

A STRIDE Threat Modeling Prompt That Skips the Workshop
Threat modeling has a scheduling problem. It's the security practice everyone agrees matters and almost nobody does, because the honest version means booking a room, three engineers, and a security le…

AI Agent Fleet Operations: A Playbook Prompt for Running Many Agents
Running one AI agent is a demo. Running twenty of them, each with its own job, its own model, and its own way of failing, is an operations problem nobody warned you about. Suddenly you need to know wh…

AI Agent Audit Trail: Design the Log Schema With a Prompt
When an AI agent does something you have to answer for later, having logs isn't the same as being able to reconstruct what happened. Stack traces tell you the code ran. They don't tell you the agent c…