AI Skill Report Card
Writing Automated Tests
Quick Start
JavaScript// Start with high-value integration tests describe('User Registration Flow', () => { it('creates account and sends welcome email', async () => { const userData = { email: 'test@example.com', password: 'secure123' }; const response = await request(app) .post('/register') .send(userData) .expect(201); expect(response.body.user.email).toBe(userData.email); expect(mockEmailService.sendWelcome).toHaveBeenCalledWith(userData.email); }); });
Recommendation▾
Add a specific template or checklist for test coverage assessment (e.g., 'Coverage Strategy Matrix' showing what to test at unit vs integration level)
Workflow
Testing Strategy:
- Start with static analysis - Set up TypeScript/ESLint first for immediate confidence
- Write integration tests - Cover critical user flows end-to-end
- Add unit tests - Focus on complex business logic and edge cases
- Monitor confidence levels - Ask "Would I deploy with confidence after these pass?"
Progress checklist for new projects:
- Configure TypeScript + ESLint
- Set up testing framework (Jest/Vitest)
- Write 3-5 integration tests for core flows
- Add unit tests for business logic
- Set up CI to run tests on every commit
Recommendation▾
Include concrete examples of test data setup/teardown patterns to reduce maintenance overhead
Examples
Example 1: High-Confidence Integration Test Input: E-commerce checkout flow Output:
JavaScriptit('completes purchase with payment processing', async () => { const order = await createTestOrder(); const paymentData = { cardToken: 'tok_visa', amount: 2999 }; const result = await checkoutService.processPurchase(order.id, paymentData); expect(result.status).toBe('completed'); expect(mockPaymentGateway.charge).toHaveBeenCalledWith(paymentData); expect(mockInventory.reserve).toHaveBeenCalledWith(order.items); });
Example 2: Business Logic Unit Test Input: Tax calculation with multiple rules Output:
JavaScriptdescribe('TaxCalculator', () => { it('applies state tax and handles tax-exempt items', () => { const items = [ { price: 100, taxable: true }, { price: 50, taxable: false } // prescription medicine ]; const tax = calculator.calculate(items, { state: 'CA', rate: 0.08 }); expect(tax).toBe(8.00); // Only $100 taxed at 8% }); });
Recommendation▾
Provide a troubleshooting section with specific symptoms and solutions (e.g., 'If tests are flaky, check for...')
Best Practices
Maximize Confidence:
- Test the happy path AND edge cases that matter to users
- Integration tests for workflows, unit tests for algorithms
- Use TypeScript to catch type errors before runtime
- Mock external services but test integration points
Minimize Maintenance:
- Test behavior, not implementation details
- Use descriptive test names that explain the scenario
- Group related tests logically
- Keep setup/teardown simple and reusable
Practical Guidelines:
- If changing code requires updating 10+ tests, you're testing implementation
- If tests pass but the feature is broken, add integration coverage
- If you're afraid to refactor because tests might break, improve test design
Common Pitfalls
Over-testing implementation:
JavaScript// BAD - Tests internal method calls expect(userService.validateEmail).toHaveBeenCalled(); // GOOD - Tests the outcome expect(result.errors).toContain('Invalid email format');
Under-testing critical paths:
- Don't skip authentication, payment, or data persistence flows
- These bugs wake you up at 2 AM - test them thoroughly
False confidence from poor tests:
- Tests that always pass regardless of code changes
- Mocking everything including the system under test
- Testing only the happy path while ignoring error conditions