Write comprehensive tests for the code that was just added or changed.
Step 1: Discover What Changed
Change under test (injected at load — already in front of you, no tool call needed):
git diff --stat HEAD 2>/dev/null || echo "(no diff vs HEAD — inspect git status manually)"
git diff HEAD 2>/dev/null || true
- The diff above is the change under test. If it is empty (already committed or amended elsewhere), run
git diff, git diff --cached, or git show HEAD to locate the change
- Read each changed file to understand the behavior being added
- Identify the project's existing test framework, patterns, and conventions by finding existing test files
- Place new test files next to the source files or in the project's established test directory. Match whatever the project already does
Step 2: Analyze Every Code Path
For each new or modified function/method/component, map out:
- Happy path. Normal input, expected output
- Edge cases. Empty input, single element, boundary values (0, 1, -1, MAX_INT)
- Null/undefined/nil. What happens with missing data
- Type boundaries. Wrong types, type coercion traps
- Error paths. Invalid input, network failures, timeouts, permission denied
- Concurrency. Race conditions, parallel calls with shared state
- State transitions. Initial state, intermediate states, final state
- Integration points. How this code interacts with its dependencies
Step 3: Write the Tests
For EACH scenario identified above, write a test. No skipping.
Structure
- One assertion per test. If a test name needs "and", split it into two tests
- Descriptive names. Test names read as sentences describing the behavior:
should return empty array when input is empty
should throw ValidationError when email format is invalid
should retry 3 times before failing on network timeout
- Arrange-Act-Assert. Set up, execute, verify. Clear separation.
What to Test
Pure functions / business logic:
- Every branch (if/else, switch, ternary)
- Every thrown error with exact error type and message
- Return value types and shapes
- Side effects (mutations, calls to external services)
API endpoints / handlers:
- Success response (status code, body shape, headers)
- Validation errors for each field (missing, wrong type, out of range)
- Authentication/authorization failures
- Rate limiting behavior if applicable
- Idempotency for non-GET methods
UI components (if applicable):
- Renders without crashing with required props
- Renders correct content for each state (loading, error, empty, populated)
- User interactions trigger correct callbacks (click, submit, type, select)
- Accessibility: focusable, keyboard navigable, correct ARIA attributes
- Conditional rendering. Each branch shows/hides correct elements
Database / data layer:
- CRUD operations return correct data
- Unique constraints reject duplicates
- Cascade deletes work as expected
- Transactions roll back on failure
Async operations:
- Successful resolution
- Rejection / error handling
- Timeout behavior
- Cancellation if supported
- Concurrent calls don't interfere
Mocking Rules
- Prefer real implementations over mocks
- Only mock at system boundaries: network, filesystem, clock, random
- Never mock the code under test
- If you mock, verify the mock was called with expected arguments
- Reset mocks between tests. No shared state leaking
Step 4: Verify
- Run the new tests. Confirm they all pass
- Temporarily break the code (change a return value or condition). Confirm at least one test fails
- If no test fails when code is broken, the tests are useless. Rewrite them
- Check coverage: every new function should have at least one test, every branch should be exercised
Output
- Complete, runnable test file(s). Not snippets
- Tests grouped by the function/component they cover
- A brief summary: how many tests, what scenarios covered, any gaps you couldn't cover and why
1---2name: test-writer3description: Write comprehensive tests for new or changed code. Use automatically after adding a function, endpoint, or component, or changing behavior, when the change has no corresponding test changes. Not for config, docs, or test-only diffs. For judging whether existing tests adequately verify a change, use the pr-test-analyzer agent instead.4---56Write comprehensive tests for the code that was just added or changed.78## Step 1: Discover What Changed910Change under test (injected at load — already in front of you, no tool call needed):1112```!13git diff --stat HEAD 2>/dev/null || echo "(no diff vs HEAD — inspect git status manually)"14```1516```!17git diff HEAD 2>/dev/null || true18```1920- The diff above is the change under test. If it is empty (already committed or amended elsewhere), run `git diff`, `git diff --cached`, or `git show HEAD` to locate the change21- Read each changed file to understand the behavior being added22- Identify the project's existing test framework, patterns, and conventions by finding existing test files23- Place new test files next to the source files or in the project's established test directory. Match whatever the project already does2425## Step 2: Analyze Every Code Path2627For each new or modified function/method/component, map out:2829- **Happy path**. Normal input, expected output30- **Edge cases**. Empty input, single element, boundary values (0, 1, -1, MAX_INT)31- **Null/undefined/nil**. What happens with missing data32- **Type boundaries**. Wrong types, type coercion traps33- **Error paths**. Invalid input, network failures, timeouts, permission denied34- **Concurrency**. Race conditions, parallel calls with shared state35- **State transitions**. Initial state, intermediate states, final state36- **Integration points**. How this code interacts with its dependencies3738## Step 3: Write the Tests3940For EACH scenario identified above, write a test. No skipping.4142### Structure4344- **One assertion per test**. If a test name needs "and", split it into two tests45- **Descriptive names**. Test names read as sentences describing the behavior:46 - `should return empty array when input is empty`47 - `should throw ValidationError when email format is invalid`48 - `should retry 3 times before failing on network timeout`49- **Arrange-Act-Assert**. Set up, execute, verify. Clear separation.5051### What to Test5253**Pure functions / business logic:**54- Every branch (if/else, switch, ternary)55- Every thrown error with exact error type and message56- Return value types and shapes57- Side effects (mutations, calls to external services)5859**API endpoints / handlers:**60- Success response (status code, body shape, headers)61- Validation errors for each field (missing, wrong type, out of range)62- Authentication/authorization failures63- Rate limiting behavior if applicable64- Idempotency for non-GET methods6566**UI components (if applicable):**67- Renders without crashing with required props68- Renders correct content for each state (loading, error, empty, populated)69- User interactions trigger correct callbacks (click, submit, type, select)70- Accessibility: focusable, keyboard navigable, correct ARIA attributes71- Conditional rendering. Each branch shows/hides correct elements7273**Database / data layer:**74- CRUD operations return correct data75- Unique constraints reject duplicates76- Cascade deletes work as expected77- Transactions roll back on failure7879**Async operations:**80- Successful resolution81- Rejection / error handling82- Timeout behavior83- Cancellation if supported84- Concurrent calls don't interfere8586### Mocking Rules8788- Prefer real implementations over mocks89- Only mock at system boundaries: network, filesystem, clock, random90- Never mock the code under test91- If you mock, verify the mock was called with expected arguments92- Reset mocks between tests. No shared state leaking9394## Step 4: Verify9596- Run the new tests. Confirm they all pass97- Temporarily break the code (change a return value or condition). Confirm at least one test fails98- If no test fails when code is broken, the tests are useless. Rewrite them99- Check coverage: every new function should have at least one test, every branch should be exercised100101## Output102103- Complete, runnable test file(s). Not snippets104- Tests grouped by the function/component they cover105- A brief summary: how many tests, what scenarios covered, any gaps you couldn't cover and why