Testing Strategies
Testing strategies I use across projects:
Testing Pyramid
/\
/ \ E2E Tests (10%)
/____\ - User workflows
/ \ - Critical paths
/________\
Integration Tests (20%)
- API endpoints
- Database interactions
Unit Tests (70%)
- Pure functions
- Business logic
Unit Testing Best Practices
// AAA Pattern: Arrange, Act, Assert
describe('UserService', () => {
it('should create user with valid data', async () => {
// Arrange
const userData = { name: 'John', email: 'john@test.com' };
const mockRepo = { save: jest.fn().mockResolvedValue(userData) };
const userService = new UserService(mockRepo);
// Act
const result = await userService.createUser(userData);
// Assert
expect(result).toEqual(userData);
expect(mockRepo.save).toHaveBeenCalledWith(userData);
});
});
Integration Testing
// Test API endpoints with real database
describe('POST /api/users', () => {
beforeEach(async () => {
await cleanDatabase();
});
it('should create user and return 201', async () => {
const response = await request(app)
.post('/api/users')
.send({ name: 'John', email: 'john@test.com' })
.expect(201);
expect(response.body.data.name).toBe('John');
});
});
E2E Testing with Cypress
describe('User Registration', () => {
it('should register new user', () => {
cy.visit('/register');
cy.get('[data-testid="name"]').type('John Doe');
cy.get('[data-testid="email"]').type('john@test.com');
cy.get('[data-testid="password"]').type('password123');
cy.get('[data-testid="submit"]').click();
cy.url().should('include', '/dashboard');
});
});
Test Data Management
- Use factories for test data
- Clean database between tests
- Mock external services
- Use test-specific configurations