Prompt file imported from ZenRay/CursorTemplate (
.cursor/commands/tdd-workflow.md). Copyright stays with the author.
/tdd-workflow β Test-Driven Development
Complete TDD workflow using Cursor Test Panel and automated testing.
What is Cursor Test Panel?
Cursor has built-in test integration:
- Shows test results inline in the editor
- Displays pass/fail status in the gutter
- Integrated with Agent for auto-test workflows
TDD Cycle with Cursor
1. Red β Write Failing Test
/tdd-workflow red
Describe: "User registration should validate email format"
Test file: src/auth/__tests__/register.test.ts
Agent generates:
- Test case with invalid email
- Assertion for error response
- Edge cases (empty, malformed, missing)
Run tests (expect failure):
npm test -- register.test.ts
Cursor Test Panel shows: π΄ 3 tests failing
2. Green β Write Minimal Code
/tdd-workflow green
Implement minimal validation to pass tests.
Don't over-engineer.
Agent generates:
- Email regex validation
- Error response format
Test Panel updates: π’ 3 tests passing
3. Refactor β Improve Code
/tdd-workflow refactor
Clean up:
- Extract validation to helper
- Improve error messages
- Add JSDoc
Test Panel stays: π’ All passing (regression safety)
Test Panel Commands
Open Test Panel
Cmd/Ctrl + Shift + P β "Cursor: Open Test Panel"
Or keyboard shortcut:
Cmd/Ctrl + Shift + T
View Test Status
/tdd-workflow status
Output:
## Test Status
| Suite | Passing | Failing | Skipped |
|-------|---------|---------|---------|
| auth | 12 β
| 0 | 0 |
| api | 45 β
| 2 π΄ | 1 βΈοΈ |
| utils | 8 β
| 0 | 0 |
Failing:
- api/users.test.ts:42 - should reject duplicate email
- api/auth.test.ts:15 - should refresh expired token
Run Affected Tests
After code changes:
/tdd-workflow run-affected
Runs only tests related to modified files.
Much faster than full suite.
YOLO Mode Integration
/tdd-workflow yolo
Enables:
1. Auto-run affected tests on file save
2. Auto-fix failing tests (if safe)
3. Stop after 3 failed attempts
4. Notify when all pass
β οΈ Requires YOLO mode enabled in settings.
Test Generation Patterns
Pattern 1: Happy Path + Edge Cases
// Generated by /tdd-workflow generate
describe('createUser', () => {
// Happy path
it('creates user with valid data', () => {
const user = createUser({ email: 'test@example.com', name: 'Test' });
expect(user.id).toBeDefined();
expect(user.email).toBe('test@example.com');
});
// Edge cases
it('rejects invalid email', () => {
expect(() => createUser({ email: 'invalid' }))
.toThrow('Invalid email format');
});
it('rejects duplicate email', async () => {
await createUser({ email: 'test@example.com' });
await expect(createUser({ email: 'test@example.com' }))
.rejects.toThrow('Email already exists');
});
it('handles empty name', () => {
const user = createUser({ email: 'test@example.com', name: '' });
expect(user.name).toBe(''); // or should it throw?
});
});
Pattern 2: API Endpoint Tests
// /tdd-workflow generate-api-test POST /api/users
describe('POST /api/users', () => {
it('creates user and returns 201', async () => {
const res = await request(app)
.post('/api/users')
.send({ email: 'test@example.com', password: 'secure123' });
expect(res.status).toBe(201);
expect(res.body).toHaveProperty('id');
expect(res.body.password).toBeUndefined(); // never return password
});
it('returns 400 for invalid input', async () => {
const res = await request(app)
.post('/api/users')
.send({ email: 'invalid' });
expect(res.status).toBe(400);
expect(res.body.errors).toContainEqual(
expect.objectContaining({ field: 'email' })
);
});
});
Pattern 3: Component Tests
// /tdd-workflow generate-component LoginForm
describe('LoginForm', () => {
it('renders email and password inputs', () => {
render(<LoginForm />);
expect(screen.getByLabelText(/email/i)).toBeInTheDocument();
expect(screen.getByLabelText(/password/i)).toBeInTheDocument();
});
it('submits form with user input', async () => {
const onSubmit = jest.fn();
render(<LoginForm onSubmit={onSubmit} />);
await userEvent.type(screen.getByLabelText(/email/i), 'test@example.com');
await userEvent.type(screen.getByLabelText(/password/i), 'password123');
await userEvent.click(screen.getByRole('button', { name: /login/i }));
expect(onSubmit).toHaveBeenCalledWith({
email: 'test@example.com',
password: 'password123'
});
});
it('shows validation errors', async () => {
render(<LoginForm />);
await userEvent.click(screen.getByRole('button', { name: /login/i }));
expect(screen.getByText(/email is required/i)).toBeInTheDocument();
});
});
Integration with Agent
Agent-Assisted TDD
"Implement user authentication using TDD"
Agent will:
1. /tdd-workflow red β Write failing tests
2. /tdd-workflow green β Implement minimal code
3. /tdd-workflow refactor β Clean up
4. Repeat for each auth feature
Auto-Generate from Code
/tdd-workflow generate-from src/utils/validation.ts
Analyzes code and generates:
- Unit tests for exported functions
- Edge case coverage
- Integration test suggestions
Coverage Goals
Recommended coverage thresholds:
| Module | Lines | Functions | Branches |
|---|---|---|---|
| Core logic | 90% | 95% | 85% |
| API handlers | 85% | 90% | 80% |
| Utilities | 80% | 85% | 75% |
| UI components | 70% | 75% | 60% |
View coverage:
/tdd-workflow coverage
Output:
## Coverage Report
| File | Lines | Functions | Branches |
|------|-------|-----------|----------|
| src/auth.ts | 92% β
| 100% β
| 88% β
|
| src/api.ts | 78% β οΈ | 85% β οΈ | 72% β οΈ |
Areas needing tests:
- src/api.ts:42 - Error handling branch
- src/api.ts:88 - Rate limiting check
Debugging Failed Tests
/tdd-workflow debug src/auth.test.ts:42
Agent:
1. Reads failing test
2. Reads implementation
3. Identifies root cause
4. Suggests fix
5. Can auto-fix if safe
Test Organization
Recommended structure:
src/
βββ components/
β βββ Button.tsx
β βββ __tests__/
β βββ Button.test.tsx # Component tests
βββ utils/
β βββ validation.ts
β βββ __tests__/
β βββ validation.test.ts # Unit tests
βββ api/
β βββ users.ts
β βββ __tests__/
β βββ users.test.ts # Integration tests
βββ e2e/ # End-to-end
βββ auth.spec.ts
CI Integration
Pre-commit hook:
#!/bin/bash
# .cursor/hooks/pre-test.sh
npm run test:staged # Run only changed tests
Quick Reference
/tdd-workflow red β Write failing test
/tdd-workflow green β Make it pass
/tdd-workflow refactor β Clean up
/tdd-workflow status β View all test status
/tdd-workflow run-affected β Run related tests
/tdd-workflow yolo β Auto-run mode
/tdd-workflow coverage β Coverage report
/tdd-workflow debug [file] β Debug failing test
Best Practices
- Test behavior, not implementation β Refactor-friendly
- One assertion per test (mostly) β Clear failure messages
- Descriptive names β
it('should reject invalid email') - Given-When-Then β Structure: arrange, act, assert
- Fast feedback β < 1 second per test file
- YOLO with care β Only in well-tested codebases
