What this prompt does
This prompt turns Claude Code into a test author for a single class or module. It hands the model a fixed contract — unit tests for every public method, edge cases (null inputs, boundary values, empty collections), error and exception paths, integration tests for your real [dependencies], and a [mock_strategy] for everything external — instead of a vague "write some tests" request. That structure is the whole point: it forces breadth (every public method) and depth (the failure paths people skip) in one pass.
It works because each instruction maps to a category of bug. Boundary and null cases catch the off-by-one and unguarded-input defects; the exception tests assert that your code fails the way it claims to; the mock strategy keeps unit tests fast and deterministic while the integration tests still exercise the wiring. Naming convention and coverage target give Claude an objective finish line, so it self-checks against [coverage]% rather than stopping at three happy-path tests.
When to use it
- You inherited a class with zero tests and need a safety net before refactoring it.
- You just wrote a service or utility and want exhaustive coverage without hand-listing every case.
- A bug slipped past your existing suite and you suspect the edge cases were never tested.
- You're enforcing a coverage gate in CI and a specific file is dragging the number down.
- You're standardizing test style across a team and want every new class to follow one
[naming_convention]. - You need both isolated unit tests and integration tests for the same class in a single, consistent batch.
Example output
For a PaymentProcessor class (PHPUnit, mock strategy = Mockery), Claude Code returns a runnable test file:
final class PaymentProcessorTest extends TestCase
{
public function test_charge_returns_receipt_on_success(): void { /* happy path */ }
/** @dataProvider invalidAmounts */
public function test_charge_rejects_invalid_amount($amount): void { /* 0, -1, null */ }
public function test_charge_throws_on_gateway_timeout(): void
{
$gateway = Mockery::mock(Gateway::class);
$gateway->shouldReceive('send')->andThrow(new TimeoutException);
$this->expectException(PaymentFailedException::class);
// ...
}
}
It typically closes with a coverage note: which methods hit the target and which branches still need a test.
Pro tips
- Name
[dependencies]precisely — "the Stripe gateway and the EloquentOrdermodel" beats "dependencies." Vague input gives you vague mocks. - Match
[mock_strategy]to your stack: Mockery or PHPUnit mocks for PHP,unittest.mockfor Python, Jest mocks for TS. A mismatch makes the tests look right but not run. - Treat
[coverage]%as a floor, not a goal. Asking for 100% invites brittle tests of trivial getters; 80-90% usually targets the code that matters. - Run the suite immediately and paste any failures back — Claude is better at fixing a red test than predicting your exact fixtures and container bindings.
- Pair it with a follow-up: "now add a mutation-testing pass" or "add tests for the private methods via their public callers" to catch assertions that pass without really checking anything.