Python

Verified against Claude Code · 2026-07-22

Generate a pytest suite that tests behavior, not implementation

A test-generation prompt that requires parametrized cases, isolated external dependencies, and named edge-case coverage, instead of a handful of near-duplicate happy-path tests that break on any refactor.

Claude CodeGitHub Copilot ChatCursor 2.1ChatGPT (GPT-5.1)4 fillable variables

The prompt

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

Write a pytest test suite for the code below. Test the documented behavior and contract, not the internal implementation — if the function's logic were rewritten to do the same thing a different way, these tests should still mostly pass.

CODE UNDER TEST
def parse_discount_code(code: str, cart_total: float) -> DiscountResult: ...

EXTERNAL DEPENDENCIES TO ISOLATE
a database session, an external tax-rate API call. Mock or fake these — do not let the test suite depend on a real network call, real file I/O, or a real database. Use pytest-mock's mocker fixture or unittest.mock.patch, patched at the point of use, not at its original definition.

CURRENT COVERAGE GAP
Nobody has ever tested what happens when the same discount code is applied twice in one cart session.

REQUIREMENTS
1. Use @pytest.mark.parametrize for any case that shares the same assertion shape with different inputs — don't hand-write five near-identical test functions when one parametrized table says the same thing more clearly.
2. Use fixtures for setup shared across tests, and scope each fixture (function, module, session) to the narrowest scope that's still correct — a session-scoped fixture holding mutable state is a bug waiting for test order to change.
3. Cover: the happy path, expired discount codes, codes with leading/trailing whitespace, a valid code where cart_total is below the minimum spend, the gap named in Nobody has ever tested what happens when the same discount code is applied twice in one cart session., and at least one case not listed that you judge worth testing — name why you added it.
4. For anything defined with async def, use pytest-asyncio's async test support — don't wrap async code in asyncio.run() inside a synchronous test.
5. Name each test after the behavior it verifies (e.g. test_returns_empty_list_when_no_matches), not test_1 or test_case_a — a failing test name should tell someone what broke without opening the file.
6. Assert on outcomes and raised exceptions with pytest.raises, never on internal call counts unless the actual requirement is "this must call X exactly once," in which case say so explicitly before asserting it.
7. Every test must be runnable in isolation and in any order — no test may rely on state a different test happened to leave behind, such as a module-level counter or a fixture mutated by an earlier test in the file. If a test genuinely needs a specific order relative to another, say so explicitly and mark it clearly, rather than depending on pytest's default file order by accident and having the suite quietly break the day someone reorders the tests for readability.

OUTPUT FORMAT
1. The test file.
2. A short list of anything you could not test without more context (e.g. a fixture needing real credentials, a race condition that needs a specific timing setup) and why.
3. A one-line map from each test back to the requirement or edge case it covers, so coverage can be checked against expired discount codes, codes with leading/trailing whitespace, a valid code where cart_total is below the minimum spend and Nobody has ever tested what happens when the same discount code is applied twice in one cart session. at a glance rather than trusted on faith.

Customize

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

Why this works

Explicitly requiring parametrize over hand-written near-duplicates changes the shape of the output, not just its length: a table of parametrized cases makes a missing row visually obvious to a reviewer, where a missing copy-pasted test function is easy to not notice at all sitting among four others that look almost identical. Naming "test behavior, not implementation" directly targets a common LLM test-generation failure — asserting on internal state or exact call counts that make the suite brittle against any refactor, even a correct one, so a passing test suite stops meaning "the behavior is right" and starts meaning "nobody touched the internals yet." The dependency-isolation instruction, including the detail about patching at the point of use rather than the original definition, is what keeps a generated suite from silently becoming an integration test that fails in CI for reasons unrelated to the code under test, such as a network blip, or from failing to actually mock anything at all because unittest.mock.patch was pointed at the wrong import path — a specific, very common mocking mistake that produces a test that looks isolated but still hits the real dependency. The coverage_gap field matters because it names a known blind spot directly rather than hoping the model happens to think of it independently — "double-applying a discount code" is exactly the kind of scenario nobody writes a test for until it causes a real incident, and naming it converts a known risk into a guaranteed test rather than a lucky one. Finally, requiring one additional case the model chooses and justifies, beyond the given lists, forces actual reasoning about the function's contract instead of just executing a checklist — the justification is what separates a genuinely useful addition from padding the test count. The isolation-and-order requirement closes a related gap: a suite that only passes when run in file order, or only when a specific test happens to run first, is passing by accident, not by design.

Verified against

Claude Code Sonnet 4.6 · 2026-07-22

Changelog

  • 2026-07-22 Initial publish, verified against Claude Code (Sonnet 4.6) on pytest 8.3.

Need this built into your business?

If a prompt isn't enough — custom software, built and maintained for you — that's Scult's day job.

EXPLORE CUSTOM SOFTWARE
All Python 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