What this prompt does
This prompt turns Copilot into a unit-test generator that goes well past a naive /tests pass. It is keyed on [language] and [test_framework] so the output uses your real tooling, and it describes the code under test through [code_description] and [functionality] so the generated tests target actual behavior rather than placeholder logic. The instruction explicitly starts from Copilot's own /tests command and then layers on the additions that command usually omits.
The structure works because it sequences the parts most generated suites skip. It uses [edge_cases] to force conditions Copilot tends to ignore, [dependencies] to drive realistic mocks for both success and failure paths, and [parameterized_scenarios] to collapse repetitive tests into a single data-driven case. It also covers async behavior with proper await and timeout handling, negative tests that assert specific error types and messages, an integration-style test across [integration_boundary] that is deliberately kept real rather than mocked, and a [coverage_goal] used to flag which branches the first generation missed. Mocking both the success and failure paths of each dependency is where most of the real coverage comes from, which is why the prompt insists on it.
When to use it
- You have untested or thinly tested service-layer code and want a thorough suite fast.
- Copilot's default
/testsoutput covers the happy path but skips edge cases. - You need mocks that simulate failure, not just success, for external dependencies.
- You have many near-identical test cases that should become data-driven instead.
- You are testing async code and want correct await and timeout handling.
- You want to push toward a specific coverage target and see which branches stay uncovered.
Example output
Expect a test file or files in your [test_framework] syntax: a base suite, additional edge-case tests for the conditions you named, mock implementations of each dependency with both success and failure variants, parameterized tests for the repetitive scenarios, async tests with proper awaits, negative tests asserting specific error types and messages, and an integration-style test that exercises the real boundary. It usually closes with notes on which branches the initial generation left uncovered relative to [coverage_goal], so you know exactly where to keep going.
Pro tips
- Be concrete in
[functionality]— "creating charges, processing refunds, handling webhooks" yields sharper tests than a vague "payment stuff." - List the failure modes you actually fear in
[edge_cases]; that is precisely where generated suites are weakest and where bugs hide. - Name every external in
[dependencies]so Copilot mocks both the success and failure paths, since the failure path is where most real coverage lives. - Pick a
[coverage_goal]you can defend; chasing 100% often just tests trivial getters instead of meaningful logic. - Keep
[integration_boundary]genuinely unmocked, such as an in-memory test database, so the integration test actually proves something. - Treat the first generation as a draft and re-prompt for the branches it admits to missing rather than accepting the whole suite wholesale.