Test Generator
Generates comprehensive test suites from source code, including unit tests, integration tests, and snapshot tests. Produces idiomatic tests with proper mocking, setup/teardown, and meaningful assertions for the detected language and test framework.
When to Use
- User asks to "write tests for this", "add test coverage", or "generate a test suite"
- Coverage reports show untested code paths
- New functions or classes are added without accompanying tests
- User asks for integration tests for API endpoints or database layers
- Snapshot tests are needed for UI components
- User wants to verify edge cases and error conditions are tested
Process
Detect the language, framework, and existing test toolchain:
- JavaScript/TypeScript → Jest, Vitest, Mocha, Jasmine
- Python → pytest, unittest
- Go →
testing package, testify
- Java → JUnit 5, Mockito
- Ruby → RSpec, Minitest
- Check for existing test files to match conventions (describe/it blocks, AAA pattern, etc.)
Read and understand the source:
- Identify all public functions, methods, and exported symbols
- Map input types, return types, and thrown exceptions
- Trace data dependencies to determine what needs mocking
- Identify side effects (DB writes, HTTP calls, file I/O)
Design the test plan before writing:
- Happy path: normal, valid inputs produce correct output
- Edge cases: empty inputs, boundary values, max/min, unicode
- Error cases: invalid inputs, missing required fields, network failures
- Side-effect verification: confirm DB calls, HTTP requests, or event emissions occurred
Set up mocks and stubs for all external dependencies:
- Replace HTTP clients with interceptors (nock, responses, httptest)
- Mock database calls using in-memory stores or query mocks
- Stub file system, clocks, and random number generators for deterministic tests
Write tests following AAA (Arrange → Act → Assert):
- Arrange: set up inputs, mocks, and preconditions
- Act: call the function or trigger the behavior
- Assert: verify return values, side effects, and error messages
Name tests descriptively using "it should…" or "given…when…then…" patterns so failures are self-explanatory.
Add setup/teardown (beforeEach/afterEach, fixtures, factory functions) to avoid repetition and ensure test isolation.
Verify generated tests compile by checking syntax and import paths against the project structure.
Output Format
Produce a complete test file (or files) with:
- Correct imports for the test framework and the module under test
- Grouped test suites (describe blocks or test classes)
- Individual test cases with clear names
- Mock/stub declarations scoped appropriately
- Inline comments explaining non-obvious test logic
// tests/userService.test.ts
import { getUserById, createUser } from '../src/userService';
import { db } from '../src/db';
jest.mock('../src/db');
describe('getUserById', () => {
beforeEach(() => jest.clearAllMocks());
it('should return the user when found', async () => {
(db.query as jest.Mock).mockResolvedValueOnce([{ id: 1, name: 'Alice' }]);
const user = await getUserById(1);
expect(user).toEqual({ id: 1, name: 'Alice' });
});
it('should return null when user is not found', async () => {
(db.query as jest.Mock).mockResolvedValueOnce([]);
const user = await getUserById(999);
expect(user).toBeNull();
});
it('should throw when the database errors', async () => {
(db.query as jest.Mock).mockRejectedValueOnce(new Error('DB down'));
await expect(getUserById(1)).rejects.toThrow('DB down');
});
});
Examples
Example Input
# src/calculator.py
def divide(a: float, b: float) -> float:
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
Example Output
# tests/test_calculator.py
import pytest
from src.calculator import divide
class TestDivide:
def test_divides_two_positive_numbers(self):
assert divide(10.0, 2.0) == 5.0
def test_divides_negative_numbers(self):
assert divide(-6.0, 3.0) == -2.0
def test_returns_float(self):
result = divide(1, 2)
assert isinstance(result, float)
assert result == 0.5
def test_raises_on_zero_divisor(self):
with pytest.raises(ValueError, match="Cannot divide by zero"):
divide(10.0, 0)
def test_handles_very_large_numbers(self):
assert divide(1e308, 1e154) == pytest.approx(1e154)
Boundaries
- Do NOT alter the source file being tested.
- Do NOT generate tests for code that is clearly auto-generated (migrations, protobuf output, etc.).
- Do NOT hardcode credentials, real API keys, or production URLs in test files.
- Do NOT create tests that depend on execution order; each test must be independent.
- If the source function's behavior is ambiguous, generate tests that document the observed behavior and add a comment flagging the ambiguity.
- Limit integration test generation to what can reasonably run in CI without external infrastructure unless a test database or mock server is already configured.
- Do NOT generate tests that require a running production service; use mocks/stubs for all external calls.
1---2name: test-generator3description: Reads source code and generates unit tests, integration tests, or snapshot tests with appropriate mocking. Invoke when asked to write tests, add test coverage, generate specs, or create test suites for functions, classes, or API endpoints.4---56# Test Generator78Generates comprehensive test suites from source code, including unit tests, integration tests, and snapshot tests. Produces idiomatic tests with proper mocking, setup/teardown, and meaningful assertions for the detected language and test framework.910## When to Use1112- User asks to "write tests for this", "add test coverage", or "generate a test suite"13- Coverage reports show untested code paths14- New functions or classes are added without accompanying tests15- User asks for integration tests for API endpoints or database layers16- Snapshot tests are needed for UI components17- User wants to verify edge cases and error conditions are tested1819## Process20211. **Detect the language, framework, and existing test toolchain**:22 - JavaScript/TypeScript → Jest, Vitest, Mocha, Jasmine23 - Python → pytest, unittest24 - Go → `testing` package, testify25 - Java → JUnit 5, Mockito26 - Ruby → RSpec, Minitest27 - Check for existing test files to match conventions (describe/it blocks, AAA pattern, etc.)28292. **Read and understand the source**:30 - Identify all public functions, methods, and exported symbols31 - Map input types, return types, and thrown exceptions32 - Trace data dependencies to determine what needs mocking33 - Identify side effects (DB writes, HTTP calls, file I/O)34353. **Design the test plan** before writing:36 - Happy path: normal, valid inputs produce correct output37 - Edge cases: empty inputs, boundary values, max/min, unicode38 - Error cases: invalid inputs, missing required fields, network failures39 - Side-effect verification: confirm DB calls, HTTP requests, or event emissions occurred40414. **Set up mocks and stubs** for all external dependencies:42 - Replace HTTP clients with interceptors (nock, responses, httptest)43 - Mock database calls using in-memory stores or query mocks44 - Stub file system, clocks, and random number generators for deterministic tests45465. **Write tests following AAA (Arrange → Act → Assert)**:47 - Arrange: set up inputs, mocks, and preconditions48 - Act: call the function or trigger the behavior49 - Assert: verify return values, side effects, and error messages50516. **Name tests descriptively** using "it should…" or "given…when…then…" patterns so failures are self-explanatory.52537. **Add setup/teardown** (`beforeEach`/`afterEach`, fixtures, factory functions) to avoid repetition and ensure test isolation.54558. **Verify generated tests compile** by checking syntax and import paths against the project structure.5657## Output Format5859Produce a complete test file (or files) with:60- Correct imports for the test framework and the module under test61- Grouped test suites (describe blocks or test classes)62- Individual test cases with clear names63- Mock/stub declarations scoped appropriately64- Inline comments explaining non-obvious test logic6566```67// tests/userService.test.ts68import { getUserById, createUser } from '../src/userService';69import { db } from '../src/db';7071jest.mock('../src/db');7273describe('getUserById', () => {74 beforeEach(() => jest.clearAllMocks());7576 it('should return the user when found', async () => {77 (db.query as jest.Mock).mockResolvedValueOnce([{ id: 1, name: 'Alice' }]);78 const user = await getUserById(1);79 expect(user).toEqual({ id: 1, name: 'Alice' });80 });8182 it('should return null when user is not found', async () => {83 (db.query as jest.Mock).mockResolvedValueOnce([]);84 const user = await getUserById(999);85 expect(user).toBeNull();86 });8788 it('should throw when the database errors', async () => {89 (db.query as jest.Mock).mockRejectedValueOnce(new Error('DB down'));90 await expect(getUserById(1)).rejects.toThrow('DB down');91 });92});93```9495## Examples9697### Example Input98```python99# src/calculator.py100def divide(a: float, b: float) -> float:101 if b == 0:102 raise ValueError("Cannot divide by zero")103 return a / b104```105106### Example Output107```python108# tests/test_calculator.py109import pytest110from src.calculator import divide111112class TestDivide:113 def test_divides_two_positive_numbers(self):114 assert divide(10.0, 2.0) == 5.0115116 def test_divides_negative_numbers(self):117 assert divide(-6.0, 3.0) == -2.0118119 def test_returns_float(self):120 result = divide(1, 2)121 assert isinstance(result, float)122 assert result == 0.5123124 def test_raises_on_zero_divisor(self):125 with pytest.raises(ValueError, match="Cannot divide by zero"):126 divide(10.0, 0)127128 def test_handles_very_large_numbers(self):129 assert divide(1e308, 1e154) == pytest.approx(1e154)130```131132## Boundaries133134- Do NOT alter the source file being tested.135- Do NOT generate tests for code that is clearly auto-generated (migrations, protobuf output, etc.).136- Do NOT hardcode credentials, real API keys, or production URLs in test files.137- Do NOT create tests that depend on execution order; each test must be independent.138- If the source function's behavior is ambiguous, generate tests that document the observed behavior and add a comment flagging the ambiguity.139- Limit integration test generation to what can reasonably run in CI without external infrastructure unless a test database or mock server is already configured.140- Do NOT generate tests that require a running production service; use mocks/stubs for all external calls.