Unit testing: test một function/class isolated, mock tất cả external dependencies — nhanh (<1ms), stable, dễ debug khi fail (chính xác biết chỗ nào sai), không cần external services.
- Tốt cho: algorithms, business logic, pure functions, utilities.
- Integration testing: test interaction giữa multiple components/services với real hoặc minimal-mock dependencies — ví dụ test API handler với real database (test container), test service với real HTTP client.
- Chậm hơn (100ms-1s), phát hiện bugs ở boundary (schema mismatch, query lỗi, API contract violation) mà unit tests không thể catch.
- Supertest pattern (Node.js): const app = express(); const response = await request(app).get('/api/users').expect(200) — test Express routes với real middleware stack, mock chỉ external services.
- Test containers: spin up real PostgreSQL/Redis trong Docker cho tests — deterministic, isolated, cleanup sau tests.
- Contract tests thay thế integration tests trong microservices khi services owned bởi different teams.
- Testing Library philosophy: 'The more your tests resemble the way your software is used, the more confidence they can give you' — integration tests thường cho more confidence per test than unit tests.
- Mock database vs real database: mock nhanh hơn nhưng có thể miss SQL syntax errors, constraint violations, query performance issues — real DB catches more real-world bugs.