Python

Verified against Claude Code · 2026-07-18

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.

Claude CodeGitHub Copilot ChatCursor 2.1ChatGPT (GPT-5.1)

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 differently, 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.

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.
2. Use fixtures for setup shared across tests, and scope each fixture (function, module, session) to the narrowest scope that's still correct.
3. Cover: the happy path, expired discount codes, codes with leading/trailing whitespace, a valid code where cart_total is below the minimum spend, 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.
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."

OUTPUT FORMAT
The test file, followed by a short list of anything you could not test without more context (e.g. a fixture needing real credentials) and why.
Customize the highlighted detailsoptional — the prompt above already works

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. Naming "test behavior, not implementation" directly targets a common LLM test-generation failure — asserting on internal state or call counts that make the suite brittle against any refactor, even a correct one. The dependency-isolation instruction 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 a shared database fixture colliding with another test run. And the instruction to add one edge case not on the known list, and justify it, forces the model to actually reason about the function's contract instead of just executing the given checklist.

Verified against

Claude Code Sonnet 4.6 · 2026-07-18

Cursor 2.1 · 2026-07-19

Changelog

  • 2026-07-19 Initial publish, verified against Claude Code (Sonnet 4.6) and Cursor 2.1 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