Claude Code

Verified against Claude Code · 2026-07-31

Make Claude Code write tests that hunt for breakage, not confirm the happy path

A test-generation prompt that enumerates required edge-case categories and forces table-driven coverage, directly countering the documented happy-path bias of LLM-written tests.

Claude CodeCursorGitHub Copilot4 fillable variables

The prompt

Ready to copy — highlighted parts are example details you can swap.

You are writing tests whose job is to find where the code below breaks, not to confirm that it works. A suite that only exercises the happy path has failed this task even if every test in it passes.

TARGET
parseDiscountCode(code, cart) in lib/checkout/discount.ts, returns a DiscountResult

TEST FRAMEWORK AND CONVENTIONS
Vitest, using describe/it blocks and the existing test/factories/cart.ts builder for fixture data.

KNOWN EDGE CASES ALREADY IN THIS CODEBASE'S HISTORY
expired codes, codes with leading or trailing whitespace, valid codes where the cart total is below the minimum spend

REQUIRED COVERAGE — CONSIDER EVERY CATEGORY, EVEN IF THE ANSWER IS 'DOES NOT APPLY, BECAUSE...'
- Boundary values: empty, zero, negative, maximum length, exactly one element versus many.
- Null, undefined, or partially malformed input, including an object missing a field the type signature promises will be present.
- Type edge cases the type system does not actually prevent at runtime, such as JSON parsed from an external API or a form field that arrives as a string when a number was expected.
- Error and exception paths — does the function fail loudly and specifically, or silently produce a wrong-but-plausible result?
- Concurrency or repeat-call cases, if the function touches any shared, cached, or module-level state.
- Adversarial input if this function ever receives anything from outside a fully trusted boundary, such as a string long enough to test a length limit, or a value shaped like an injection attempt even if the function is not directly a security surface — a test suite that never tries an unexpected shape cannot tell you whether the function degrades safely or not.
- Every item listed under known edge cases above, even one that seems unlikely to matter today.

FORMAT
- Table-driven or parametrized tests, one assertion pattern reused across many named cases, not a wall of near-identical copy-pasted test functions where a missing row is invisible.
- Name each case after the behavior it verifies, not test1, test2, or a description of the input alone with no stated expectation.
- Do not write a snapshot test unless explicitly asked for one.
- Follow the existing conventions in Vitest, using describe/it blocks and the existing test/factories/cart.ts builder for fixture data. for fixtures and setup rather than inventing a parallel pattern this codebase does not already use elsewhere.

AFTER THE TESTS
List any coverage gap that could not be closed in this pass and exactly why — it needs a live network call, a fixture that does not exist yet, or a dependency this environment cannot exercise — rather than silently shipping a suite that looks complete but is not.

If 85% line coverage on lib/checkout/, enforced in CI states a required coverage threshold and this suite would not meet it, say so explicitly rather than presenting the suite as sufficient by omission, and name specifically which untested branch would need a case added to close the gap.

Customize

Optional — swap in your own details for the highlighted parts above.

Why this works

Left unconstrained, LLM-generated tests mirror the shape of the code they are testing rather than adversarially probing it — a well-documented bias toward happy-path coverage, because the model is pattern-matching 'what this function does' rather than reasoning about 'how this function could be called wrong'. Explicitly enumerating edge-case categories such as boundaries, null and undefined, type edge cases, error paths, and concurrency converts an implicit judgment call into an explicit checklist the model has to work through category by category, which is harder to shortcut than an open-ended 'write tests for this'. The known-edge-cases variable exists because the model has no other way to access a codebase's actual failure history — a bug already fixed once in this exact function is exactly the case worth forcing into the suite by name rather than hoping the model rediscovers it from the code alone, and this is the one thing a generic 'write good tests' instruction structurally cannot do, since it has no channel for injecting institutional memory the code itself does not encode. Requiring table-driven format over copy-pasted test functions is also a coverage mechanism, not just a style preference: a missing row in a table is visually obvious to a reviewer scanning the case list, where a missing near-duplicate function among many similar ones is easy to overlook entirely. The closing instruction to name coverage gaps explicitly, rather than let a finished-looking suite imply completeness, counters the natural framing that 'these are the tests I wrote' reads as done unless the model is specifically asked to audit its own output against a stated bar. Naming a coverage threshold to check against, when one exists, converts that self-audit from a subjective impression into a checkable number — a model told only to write good tests has no way to know whether it has done enough, while a model told the exact percentage a CI gate enforces can flag a real, specific shortfall rather than a vague sense of thoroughness that a reviewer has no way to independently verify either.

Verified against

Claude Code Sonnet 4.6 · 2026-07-31

Cursor 2.1 · 2026-07-31

Changelog

  • 2026-07-31 Initial publish, verified against Claude Code (Sonnet 4.6) and Cursor 2.1.

Building this for real?

This is a free starting point. If you'd rather have custom software built and running for your business, that's Scult's day job.

EXPLORE CUSTOM SOFTWARE
All Claude Code prompts

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY