Skip to content

Testing Patterns

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:

  • Time-consuming test writing
  • Incomplete edge case coverage
  • Maintenance burden as code evolves
  • Difficulty testing complex scenarios

AI-powered testing benefits:

  • Generate tests in seconds not hours
  • Discover edge cases humans miss
  • Auto-update tests as code changes
  • Create complex test scenarios effortlessly

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

  1. Analyze the Code

    // Target function
    export 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;
    }
  2. Request Comprehensive Tests

    @file payment.js
    Generate comprehensive tests for processPayment including:
    1. Happy path scenarios
    2. All error conditions
    3. Edge cases
    4. Async behavior
    5. Mock external dependencies
    6. Test payment gateway failures
    7. Verify all side effects
  3. 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
    });
    });
    });

Pattern 2: Test-Driven Development with AI

Section titled “Pattern 2: Test-Driven Development with AI”
// 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 tests
describe('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');
});
});
// 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 test
it('should calculate discount', () => {
const result = calculateDiscount(100, 0.1);
expect(result).toBeTruthy(); // Weak assertion
});
// AI enhances to strong test
it('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 tests
describe('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`
);
});
});
});
});
});
});
// 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 tests
import 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 tests
describe('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
MetricManual TestingAI-PoweredImprovement
Test creation time4 hours20 minutes92% faster
Code coverage45%85%89% increase
Edge cases found5-1030-505x more
Maintenance time2 hrs/week15 min/week87% less
Bug escape rate12%3%75% reduction
  • Clear understanding of requirements
  • Test environment prepared
  • Dependencies mocked/stubbed
  • Test data available
  • CI/CD pipeline ready
  • Tests are independent
  • Clear test descriptions
  • Proper setup/teardown
  • No hardcoded values
  • Fast execution time
  • Happy paths tested
  • Error conditions covered
  • Edge cases included
  • Performance validated
  • Security scenarios tested

Master testing patterns to:

  • Achieve 80%+ coverage effortlessly
  • Catch bugs before production
  • Reduce QA cycle time
  • Enable confident refactoring

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.