T

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.

SkillCommunitytestingv1.0.0MIT
0 views0 copies

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

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates