Skip to content
All essays
CraftFebruary 13, 20258 min

Testing Strategies: Unit, Integration, and E2E Testing

Master software testing strategies. Learn unit testing, integration testing, and E2E testing best practices.

Ü
Ümit Uz
Mobile & Full Stack Developer

Testing Pyramid

          /         /E2E        (10%)
        /------       /Integration (30%)
      /----------     /  Unit Tests  (60%)
    /--------------```

## Unit Testing

### What to Test

// Jest example describe('User Service', () => { test('should create user', async () => { const userData = { name: 'John', email: 'john@example.com' };

const user = await createUser(userData);

expect(user.id).toBeDefined(); expect(user.name).toBe('John'); });

test('should not create user with invalid email', async () => { const userData = { name: 'John', email: 'invalid' };

await expect(createUser(userData)).rejects.toThrow(); }); });


## Integration Testing

### API Testing

// Supertest example import request from 'supertest'; import app from '../app';

describe('POST /api/users', () => { test('should create user', async () => { const response = await request(app) .post('/api/users') .send({ name: 'John', email: 'john@example.com' }) .expect(201) .expect('Content-Type', /json/);

expect(response.body).toHaveProperty('id'); }); });


## End-to-End Testing

### Playwright Example

// Playwright E2E test import { test, expect } from '@playwright/test';

test('user registration flow', async ({ page }) => { await page.goto('/register');

await page.fill('[name="name"]', 'John'); await page.fill('[name="email"]', 'john@example.com'); await page.fill('[name="password"]', 'SecurePass123!'); await page.click('button[type="submit"]');

await expect(page).toHaveURL('/dashboard'); await expect(page.locator('h1')).toContainText('Welcome'); });


## Best Practices

1. **Test behavior, not implementation**: Focus on what, not how
2. **Keep tests independent**: Each test should run alone
3. **Use descriptive names**: Explain what's being tested
4. **Mock external dependencies**: Isolate unit tests
5. **Test edge cases**: Don't just test happy paths

## CI/CD Integration

GitHub Actions

name: Test

on: [push, pull_request]

jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Install dependencies run: npm ci - name: Run tests run: npm test - name: Run E2E tests run: npm run test:e2e


## Measuring Test Coverage

Generate coverage report

npm test -- --coverage

Target specific coverage

npm test -- --coverage --coverageReporters=html


## Conclusion

Good tests catch bugs early. Invest in testing for better code quality and confidence.
Next essay
Design Patterns: Gang of Four (GoF) in Modern JavaScript