Test Generation
AI writes comprehensive test suites
Transform testing from a chore into a superpower. Learn AI-driven patterns that generate comprehensive test suites, maintain them automatically, and catch bugs before production.
Traditional testing challenges:
AI-powered testing benefits:
Impact: Achieve 80%+ test coverage 10x faster while catching 3x more bugs.
Test Generation
AI writes comprehensive test suites
Edge Case Discovery
Find scenarios you didn’t consider
Test Maintenance
Keep tests in sync with code changes
Coverage Optimization
Target untested code intelligently
Analyze the Code
// Target functionexport async function processPayment(order, paymentMethod) { if (!order || !order.total) { throw new Error('Invalid order'); }
if (order.total <= 0) { throw new Error('Order total must be positive'); }
if (!isValidPaymentMethod(paymentMethod)) { throw new Error('Invalid payment method'); }
const result = await paymentGateway.charge({ amount: order.total, currency: order.currency || 'USD', method: paymentMethod });
if (result.success) { await updateOrderStatus(order.id, 'paid'); await sendConfirmationEmail(order.customerEmail); }
return result;}
Request Comprehensive Tests
@file payment.js
Generate comprehensive tests for processPayment including:1. Happy path scenarios2. All error conditions3. Edge cases4. Async behavior5. Mock external dependencies6. Test payment gateway failures7. Verify all side effects
AI Generates Complete Test Suite
describe('processPayment', () => { let mockPaymentGateway; let mockUpdateOrderStatus; let mockSendConfirmationEmail;
beforeEach(() => { // AI sets up all necessary mocks mockPaymentGateway = { charge: jest.fn() }; mockUpdateOrderStatus = jest.fn(); mockSendConfirmationEmail = jest.fn(); });
describe('happy path', () => { it('should process valid payment successfully', async () => { const order = { id: '123', total: 99.99, customerEmail: 'test@example.com' };
mockPaymentGateway.charge.mockResolvedValue({ success: true, transactionId: 'tx-123' });
const result = await processPayment(order, 'credit_card');
expect(mockPaymentGateway.charge).toHaveBeenCalledWith({ amount: 99.99, currency: 'USD', method: 'credit_card' });
expect(mockUpdateOrderStatus).toHaveBeenCalledWith('123', 'paid'); expect(mockSendConfirmationEmail).toHaveBeenCalledWith('test@example.com'); expect(result.success).toBe(true); });
it('should handle custom currency', async () => { // AI generates currency test }); });
describe('error conditions', () => { it('should throw error for missing order', async () => { await expect(processPayment(null, 'credit_card')) .rejects.toThrow('Invalid order'); });
it('should throw error for zero total', async () => { const order = { id: '123', total: 0 }; await expect(processPayment(order, 'credit_card')) .rejects.toThrow('Order total must be positive'); });
// AI generates all other error scenarios });
describe('edge cases', () => { it('should handle payment gateway timeout', async () => { // AI creates timeout scenario });
it('should handle concurrent payments', async () => { // AI creates race condition test }); });});
// Step 1: Describe what you want/** * @cursor Create a function that: * - Validates email addresses * - Returns normalized email (lowercase, trimmed) * - Handles subaddressing (user+tag@example.com) * - Validates against common typos * * Write tests first, then implementation */
// AI generates testsdescribe('validateEmail', () => { it('should validate correct emails', () => { expect(validateEmail('user@example.com')).toBe('user@example.com'); expect(validateEmail('USER@EXAMPLE.COM')).toBe('user@example.com'); expect(validateEmail(' user@example.com ')).toBe('user@example.com'); });
it('should handle subaddressing', () => { expect(validateEmail('user+tag@example.com')).toBe('user@example.com'); expect(validateEmail('user+newsletter@gmail.com')).toBe('user@gmail.com'); });
it('should reject invalid emails', () => { expect(() => validateEmail('invalid')).toThrow(); expect(() => validateEmail('@example.com')).toThrow(); expect(() => validateEmail('user@')).toThrow(); });
it('should fix common typos', () => { expect(validateEmail('user@gmial.com')).toBe('user@gmail.com'); expect(validateEmail('user@yahooo.com')).toBe('user@yahoo.com'); });});
// Behavior-Driven Development with AI/** * @cursor Create shopping cart with BDD tests: * * Feature: Shopping Cart * As a customer * I want to add items to my cart * So that I can purchase multiple items * * Scenarios to test: * - Adding items * - Removing items * - Updating quantities * - Applying discounts * - Calculating totals */
// AI generates BDD-style testsdescribe('Shopping Cart', () => { describe('when adding items', () => { it('should add new item to empty cart', () => { const cart = new ShoppingCart(); cart.addItem({ id: '1', name: 'Book', price: 10 });
expect(cart.items).toHaveLength(1); expect(cart.total).toBe(10); });
it('should increase quantity for existing item', () => { const cart = new ShoppingCart(); cart.addItem({ id: '1', name: 'Book', price: 10 }); cart.addItem({ id: '1', name: 'Book', price: 10 });
expect(cart.items).toHaveLength(1); expect(cart.items[0].quantity).toBe(2); expect(cart.total).toBe(20); }); });
// More scenarios...});
// Step 1: Analyze existing tests/** * @cursor Analyze these tests and identify: * 1. What mutations would still pass * 2. Missing assertions * 3. Untested branches * 4. Weak test cases * * Then enhance the tests to catch all mutations */
// Original weak testit('should calculate discount', () => { const result = calculateDiscount(100, 0.1); expect(result).toBeTruthy(); // Weak assertion});
// AI enhances to strong testit('should calculate discount correctly', () => { const result = calculateDiscount(100, 0.1); expect(result).toBe(90); // Exact value expect(result).toBeGreaterThan(0); // Positive expect(result).toBeLessThan(100); // Less than original
// Test boundary conditions expect(calculateDiscount(100, 0)).toBe(100); expect(calculateDiscount(100, 1)).toBe(0);
// Test invalid inputs expect(() => calculateDiscount(-100, 0.1)).toThrow(); expect(() => calculateDiscount(100, 1.5)).toThrow();});
// Generate visual regression tests/** * @cursor Create visual regression tests for all components: * 1. Generate test for each component state * 2. Include responsive breakpoints * 3. Test dark/light themes * 4. Handle loading/error states * 5. Capture interaction states (hover, focus) */
// AI generates comprehensive visual testsdescribe('Button Visual Regression', () => { const sizes = ['small', 'medium', 'large']; const variants = ['primary', 'secondary', 'danger']; const themes = ['light', 'dark']; const states = ['default', 'hover', 'focus', 'disabled'];
sizes.forEach(size => { variants.forEach(variant => { themes.forEach(theme => { states.forEach(state => { it(`should match ${size} ${variant} ${state} in ${theme} theme`, async () => { const component = render( <ThemeProvider theme={theme}> <Button size={size} variant={variant} disabled={state === 'disabled'} > Click me </Button> </ThemeProvider> );
if (state === 'hover') { await userEvent.hover(component.getByRole('button')); } else if (state === 'focus') { await userEvent.tab(); }
await expect(component).toMatchScreenshot( `button-${size}-${variant}-${state}-${theme}.png` ); }); }); }); }); });});
// Full page visual testing/** * @cursor Create page-level visual tests: * 1. Test at multiple viewport sizes * 2. Test with different data states * 3. Test error boundaries * 4. Test loading states * 5. Test animations disabled */
describe('Dashboard Visual Tests', () => { const viewports = [ { width: 375, height: 667, name: 'mobile' }, { width: 768, height: 1024, name: 'tablet' }, { width: 1920, height: 1080, name: 'desktop' } ];
viewports.forEach(({ width, height, name }) => { it(`should render dashboard on ${name}`, async () => { await page.setViewport({ width, height }); await page.goto('/dashboard'); await page.waitForSelector('[data-loaded="true"]');
const screenshot = await page.screenshot({ fullPage: true, animations: 'disabled' });
expect(screenshot).toMatchImageSnapshot({ customSnapshotIdentifier: `dashboard-${name}`, threshold: 0.01 }); }); });});
// Generate performance test suite/** * @cursor Create performance tests for our API: * 1. Load testing (normal traffic) * 2. Stress testing (peak traffic) * 3. Spike testing (sudden traffic) * 4. Endurance testing (sustained load) * 5. Measure response times, error rates, throughput */
// AI generates k6 performance testsimport http from 'k6/http';import { check, sleep } from 'k6';import { Rate } from 'k6/metrics';
const errorRate = new Rate('errors');
export const options = { stages: [ { duration: '2m', target: 100 }, // Ramp up { duration: '5m', target: 100 }, // Stay at 100 users { duration: '2m', target: 200 }, // Ramp to 200 { duration: '5m', target: 200 }, // Stay at 200 { duration: '2m', target: 0 }, // Ramp down ], thresholds: { http_req_duration: ['p(95) < 500'], // 95% under 500ms errors: ['rate < 0.1'], // Error rate under 10% },};
export default function () { // Test user login flow const loginRes = http.post('https://api.example.com/login', { email: 'test@example.com', password: 'password123' });
check(loginRes, { 'login successful': (r) => r.status === 200, 'response time OK': (r) => r.timings.duration < 500, });
errorRate.add(loginRes.status !== 200);
sleep(1); // Think time
// Test API endpoints with auth const token = loginRes.json('token'); const headers = { Authorization: `Bearer ${token}` };
// AI generates tests for all endpoints...}
// AI generates property-based tests/** * @cursor Create property-based tests using fast-check: * Test mathematical properties that should always hold */
import fc from 'fast-check';
describe('Array utilities', () => { it('should maintain length when shuffling', () => { fc.assert( fc.property(fc.array(fc.integer()), (arr) => { const shuffled = shuffle([...arr]); return shuffled.length === arr.length; }) ); });
it('should contain same elements after shuffle', () => { fc.assert( fc.property(fc.array(fc.integer()), (arr) => { const shuffled = shuffle([...arr]); const sortedOriginal = [...arr].sort(); const sortedShuffled = [...shuffled].sort(); return JSON.stringify(sortedOriginal) === JSON.stringify(sortedShuffled); }) ); });});
// Consumer-driven contract tests/** * @cursor Generate contract tests between: * - Frontend (consumer) * - Backend API (provider) * * Include all endpoints and data formats */
// AI generates Pact testsdescribe('User API Contract', () => { const provider = new Pact({ consumer: 'Frontend', provider: 'UserAPI', });
describe('get user', () => { it('should return user details', async () => { // Consumer expectation await provider.addInteraction({ state: 'user exists', uponReceiving: 'a request for user', withRequest: { method: 'GET', path: '/users/123', headers: { Accept: 'application/json' }, }, willRespondWith: { status: 200, headers: { 'Content-Type': 'application/json' }, body: { id: '123', name: like('John Doe'), email: term({ matcher: '.+@.+\\..+', generate: 'john@example.com' }), createdAt: iso8601DateTime(), }, }, });
// Test consumer code const user = await fetchUser('123'); expect(user.id).toBe('123'); expect(user.name).toBeTruthy(); expect(user.email).toMatch(/@/); }); });});
// Auto-update tests when code changes/** * @cursor The processOrder function has changed. * Update all related tests to match the new signature * and behavior while maintaining coverage. * * Old: processOrder(orderId, userId) * New: processOrder(order, options) */
// AI updates all affected tests automatically
Metric | Manual Testing | AI-Powered | Improvement |
---|---|---|---|
Test creation time | 4 hours | 20 minutes | 92% faster |
Code coverage | 45% | 85% | 89% increase |
Edge cases found | 5-10 | 30-50 | 5x more |
Maintenance time | 2 hrs/week | 15 min/week | 87% less |
Bug escape rate | 12% | 3% | 75% reduction |
Master testing patterns to:
Continue with:
Remember: The best test suite is one that catches bugs, runs fast, and maintains itself. Let AI handle the repetitive parts while you focus on test strategy and quality.