Testing AI-Generated Code
AI writes code fast. Testing ensures it works. Learn how to test AI output effectively and build confidence in your vibecoded projects.
Testing AI-Generated Code
AI writes fast. Testing proves it works. Don’t ship without it.
Testing is how you build confidence. It’s how you know the code actually does what you asked. It’s how you catch the edge cases AI missed.
What you’ll learn:
- Vibecoding TDD: tests as specifications
- 3 patterns for generating tests
- What to test (and what to skip)
- Copy-paste prompts for common scenarios
| Test Type | When to Use | AI Prompt Start |
|---|---|---|
| Unit | Functions, utilities | ”Write tests for this function…” |
| Integration | API endpoints, DB | ”Write integration tests…” |
| Component | React/Vue/etc. | ”Write Testing Library tests…” |
| E2E | Critical user flows | ”Write Playwright tests…” |
The Testing Mindset for Vibecoding
Traditional TDD: Write tests first, then implement.
Vibecoding TDD: Tell AI what to test, then have AI implement to pass.
Write tests for a function that:
- Takes an array of numbers
- Returns the top N largest values
- Handles edge cases: empty array, N > array length, negative numbers
Use Vitest. Don't implement the function yet.
AI writes tests. Then:
Now implement the function to make all tests pass.
The tests become your specification. AI implements to match.
Test Generation Patterns
Pattern 1: Test from Spec
You have requirements. Turn them into tests.
I need a password validator with these rules:
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character (!@#$%^&*)
Generate comprehensive tests for these rules.
Include edge cases and boundary conditions.
Use Jest with TypeScript.
Pattern 2: Test from Code
AI wrote code. Now test it.
Generate tests for this function:
[paste function]
Cover:
- Normal usage (happy path)
- Edge cases (empty input, null, boundary values)
- Error cases (invalid input, exceptions)
- Return value types
Framework: Vitest
Pattern 3: Test from Behavior
You know what it should do. Let AI figure out the test cases.
I have a shopping cart that:
- Adds items with quantities
- Removes items
- Calculates totals with tax
- Applies discount codes
- Validates stock availability
What test cases would comprehensively cover this?
Generate the tests, I'll implement the cart after.
Testing Different Code Types
Testing Functions
Test this utility function:
function formatCurrency(cents: number, locale = 'en-US'): string {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency: 'USD'
}).format(cents / 100);
}
Include tests for:
- Positive amounts
- Zero
- Negative amounts (refunds)
- Very large amounts
- Different locales
- Invalid input
Testing API Routes
Generate tests for this Next.js API route:
[paste route code]
Test:
- Successful responses
- Validation errors (400)
- Auth errors (401/403)
- Not found (404)
- Server errors (500)
Mock the database with [your mock approach].
Use next-test-api-route-handler or similar.
Testing React Components
Generate tests for this component:
[paste component]
Test:
- Renders correctly with props
- User interactions (clicks, typing)
- Loading states
- Error states
- Accessibility (role, labels)
Use React Testing Library.
Focus on behavior, not implementation.
Testing Hooks
Generate tests for this custom hook:
[paste hook]
Test:
- Initial state
- State changes after actions
- Async behavior
- Cleanup
- Edge cases
Use @testing-library/react-hooks.
The Review-Test-Refine Loop
When AI generates code, test before trusting:
- AI generates code
- You request tests
Write tests for the code you just generated. Be adversarial - try to break it. - Run tests
- If tests fail:
These tests failed: [paste failures] Fix the implementation to pass all tests. - If tests pass: Ship it!
Test Quality Checklist
Ask AI to evaluate test quality:
Review these tests for quality:
[paste tests]
Check for:
- [ ] Tests actually assert something meaningful
- [ ] Edge cases covered
- [ ] No false positives (tests that pass when they shouldn't)
- [ ] Tests are independent (no shared state)
- [ ] Readable test names
- [ ] Proper setup/teardown
What's missing? What could be stronger?
Mutation Testing with AI
Find weak tests by asking AI to break them:
Here's my function and its tests:
Function:
[paste function]
Tests:
[paste tests]
Can you modify the function in a way that's clearly
wrong but would still pass all these tests?
If yes, what test am I missing?
Integration Testing
For features that span multiple components:
Generate integration tests for the user registration flow:
1. User fills out form
2. Form validates input
3. API creates user
4. Email verification sent
5. User clicks link
6. Account activated
Test the full flow, mocking only external services
(email provider, etc).
Test Maintenance
When you modify AI-generated code:
I changed this function:
Before:
[old code]
After:
[new code]
Update the tests to cover the new behavior.
Keep existing tests that still apply.
Quick Test Templates
Unit Test Template
describe('[FunctionName]', () => {
it('should [expected behavior] when [condition]', () => {
// Arrange
const input = ...;
// Act
const result = functionName(input);
// Assert
expect(result).toBe(...);
});
});
Component Test Template
describe('<ComponentName />', () => {
it('renders [element] when [condition]', () => {
render(<ComponentName prop={value} />);
expect(screen.getByRole('...')).toBeInTheDocument();
});
it('calls [handler] when user [action]', async () => {
const handler = vi.fn();
render(<ComponentName onAction={handler} />);
await userEvent.click(screen.getByRole('button'));
expect(handler).toHaveBeenCalledWith(...);
});
});
API Test Template
describe('POST /api/resource', () => {
it('returns 201 with valid data', async () => {
const response = await request(app)
.post('/api/resource')
.send({ valid: 'data' });
expect(response.status).toBe(201);
});
it('returns 400 with invalid data', async () => {
const response = await request(app)
.post('/api/resource')
.send({ invalid: 'data' });
expect(response.status).toBe(400);
});
});
Key Takeaways
- Test first when possible — Specs become tests, AI implements to pass
- Always test AI output — AI makes mistakes, tests catch them
- Be adversarial — Try to break your code
- Use AI to review tests — Find gaps in coverage
- Keep tests simple — Readable tests are maintainable tests
Quick Test Generation Prompts
For a function:
Write tests for this function. Include:
- Happy path (normal usage)
- Edge cases (empty input, boundary values)
- Error cases (invalid input, exceptions)
For a React component:
Write React Testing Library tests for this component.
Test: renders correctly, user interactions, accessibility.
For an API endpoint:
Write integration tests for this endpoint.
Cover: 200 success, 400 validation, 401 auth, 500 errors.
🎯 Try It Now
- Open code you wrote recently (with AI or without)
- Copy this prompt:
Write comprehensive tests for this code. Include happy path, edge cases, and error cases. - Paste your code after the prompt
- Run the tests
If tests fail, you just found bugs before your users did. That’s the point.
Related Resources
Guides:
- Refactoring Patterns — Improve code safely with tests
- Debugging with AI — Fix issues when tests fail
- Iterative Development — Build-test-refine loop
Cheatsheets:
- AI Debugging Checklist — When tests reveal bugs
- Common Errors — Quick fixes
Blog:
- 7 Mistakes to Avoid — Including testing mistakes
Next: Refactoring Patterns — Improve code without breaking it