Testing Strategy Skill
Comprehensive testing methodology covering unit, integration, and end-to-end testing strategies. Generates test plans, writes tests following best practices, and ensures proper coverage of edge cases and error paths.
Description
This skill provides a structured testing methodology that covers all testing levels — unit, integration, and e2e. It helps plan test strategies, write effective tests, identify coverage gaps, and follow testing best practices.
Instructions
When the user asks about testing, follow the appropriate workflow:
Test Planning
For new features or modules, create a test plan:
## Test Plan: User Authentication Module ### Unit Tests (fast, isolated) | Test | Input | Expected Output | |------|-------|-----------------| | Valid password hash | "P@ssw0rd!" | bcrypt hash string | | Invalid email format | "not-email" | ValidationError | | Token generation | userId | JWT with correct claims | | Token expiry | expired token | TokenExpiredError | | Password too short | "abc" | ValidationError | ### Integration Tests (with dependencies) | Test | Components | Expected Behavior | |------|------------|-------------------| | Login flow | Auth + DB + JWT | Returns token + sets cookie | | Registration | Auth + DB + Email | Creates user + sends welcome email | | Rate limiting | Auth + Redis | 429 after 5 failed attempts | ### E2E Tests (full stack) | Test | User Flow | |------|-----------| | Happy path login | Navigate → enter creds → see dashboard | | Password reset | Request reset → check email → new password → login | | Session expiry | Login → wait → action → redirect to login |
Writing Unit Tests
// Follow AAA pattern: Arrange, Act, Assert describe('AuthService', () => { describe('validatePassword', () => { it('should accept valid passwords', () => { // Arrange const password = 'ValidP@ss123'; // Act const result = AuthService.validatePassword(password); // Assert expect(result.isValid).toBe(true); expect(result.errors).toHaveLength(0); }); it('should reject passwords without uppercase', () => { const result = AuthService.validatePassword('nouppercase123!'); expect(result.isValid).toBe(false); expect(result.errors).toContain('Must contain uppercase letter'); }); it('should reject empty strings', () => { const result = AuthService.validatePassword(''); expect(result.isValid).toBe(false); }); // Edge cases it('should handle null input', () => { expect(() => AuthService.validatePassword(null as any)).toThrow(); }); it('should handle unicode characters', () => { const result = AuthService.validatePassword('V@lid123\u00e9'); expect(result.isValid).toBe(true); }); }); });
Writing Integration Tests
describe('POST /api/auth/login', () => { let app: Express; let db: Database; beforeAll(async () => { db = await createTestDatabase(); app = createApp({ db }); await seedTestUser(db, { email: '[email protected]', password: 'Test123!' }); }); afterAll(async () => { await db.close(); }); it('should return 200 with valid credentials', async () => { const res = await request(app) .post('/api/auth/login') .send({ email: '[email protected]', password: 'Test123!' }); expect(res.status).toBe(200); expect(res.body).toHaveProperty('token'); expect(res.headers['set-cookie']).toBeDefined(); }); it('should return 401 with wrong password', async () => { const res = await request(app) .post('/api/auth/login') .send({ email: '[email protected]', password: 'wrong' }); expect(res.status).toBe(401); expect(res.body.error).toBe('Invalid credentials'); }); it('should return 429 after 5 failed attempts', async () => { for (let i = 0; i < 5; i++) { await request(app).post('/api/auth/login') .send({ email: '[email protected]', password: 'wrong' }); } const res = await request(app).post('/api/auth/login') .send({ email: '[email protected]', password: 'wrong' }); expect(res.status).toBe(429); }); });
Test Quality Checklist
- [ ] Tests are independent (no shared mutable state) - [ ] Each test asserts ONE behavior - [ ] Test names describe the expected behavior, not the implementation - [ ] Edge cases covered: null, undefined, empty, boundary values - [ ] Error paths tested, not just happy paths - [ ] No hardcoded delays (use waitFor/polling instead of sleep) - [ ] Tests run in < 30 seconds (unit), < 2 minutes (integration) - [ ] No flaky tests (deterministic, no time-dependent assertions)
Rules
- Follow AAA pattern: Arrange, Act, Assert
- One assertion per test (multiple assertions only if testing the same behavior)
- Test behavior, not implementation — do not test private methods directly
- Use descriptive test names:
should return 404 when user not found - Mock external services in unit tests, use them in integration tests
- Never use
sleep()in tests — use proper async waiting - Set up and tear down test data per test or test suite, not globally
- Cover edge cases: empty inputs, null values, boundary conditions, error states
- Aim for 80% coverage on business logic, do not chase 100% on utility code
- If a test is hard to write, the code probably needs refactoring
Examples
User: Write tests for this function Action: Analyze the function, identify happy path + edge cases + error cases, write comprehensive test suite
User: Create a test plan for the payment module Action: Generate structured plan with unit, integration, and e2e tests organized by scenario
User: Why is this test flaky? Action: Analyze for common causes: timing issues, shared state, non-deterministic data, race conditions
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.