What this prompt does
It turns "this module has no tests" into a concrete plan and then the tests themselves. The first instruction, read the module and its neighbours, then list every public function and branch condition, forces the model to map the actual surface area before writing a single assertion. That enumeration is what stops it from testing three obvious methods and ignoring the early-return on line 40. Tests come next, split deliberately into happy path, edge cases, and error paths, so you get coverage of the branches you just listed, not a pile of redundant happy-path checks.
Two clauses do the heavy lifting for trust. "Match existing test style (naming, factories, setup)" makes the output drop into your suite instead of fighting it, reusing your factories and base test case rather than inventing fixtures. "Include at least one integration test that exercises the real dependency when feasible" pushes past pure mocks so something verifies the module against a real database, queue, or API. Finally, reporting the coverage percentage and any code intentionally left untested with a reason gives you an auditable result and an honest gap list, not a vague "done".
When to use it
- A service, action, or job class you inherited has zero tests and you need a safety net before refactoring it.
- Coverage reports flag a specific file as a red zone and you want it brought up to parity with the rest of the suite.
- A bug just shipped from an untested branch and you want the whole module locked down, not just that one line.
- You are adding tests during a PR and need them to match the team's naming, factory, and setup conventions exactly.
- You want one genuine integration test through the real dependency, not a wall of mocks that prove nothing.
Example output
Public surface: createOrder(), cancelOrder(), refund() — 3 methods, 7 branches.
tests/Unit/Services/OrderServiceTest.php
✓ it_creates_an_order_with_valid_items (happy)
✓ it_throws_when_cart_is_empty (error: empty guard)
✓ it_caps_quantity_at_stock_limit (edge: qty > stock)
✓ it_refuses_to_cancel_a_shipped_order (error: status guard)
tests/Feature/Services/OrderServiceIntegrationTest.php
✓ it_persists_order_and_decrements_stock (real DB, RefreshDatabase)
Coverage: OrderService.php 91% lines / 86% branches.
Untested: refund() Stripe webhook path — needs live signature; left for a
contract test. Logger fallback in catch block — unreachable in test env.
Pro tips
- Point
[module_path]at one file, not a directory. The enumeration step degrades fast across many classes; loop the prompt per file for clean, reviewable diffs. - Set
[test_framework]to the exact runner and version (PHPUnit, Pest, Vitest, pytest). Pest and PHPUnit generate very different syntax, and naming it wrong gives you tests that will not run. - Before running it, make sure a real example test exists nearby. "Match existing style" only works if there is a style to copy; on a greenfield module, paste one canonical test into context first.
- Treat the reported coverage number as a claim to verify, not a fact. Actually run the suite with coverage; models routinely overstate the percentage.
- Pair it with a follow-up: "now mutate three of these tests to fail and confirm they catch it." High coverage with assertions that never fail is the classic trap this exposes.