Testing: Overview và Roadmap
Đây là section về Software Testing trong engineering KB. Mục tiêu không phải là viết test cho có — mà là viết test đúng chỗ, đúng loại, và đúng mức độ để tự tin ship code.
💡 Interview: "Testing không phải là về coverage number. Là về việc bạn có thể refactor mà không sợ không?"
Cấu trúc section
testing/
├── README.md ← file này
├── testing-pyramid-and-strategy.md ← Unit/Integration/E2E — chọn đúng tầng
├── mocks-stubs-fakes.md ← Mock/Stub/Fake/Spy — dùng đúng tool
├── integration-and-contract.md ← testcontainers, Pact, golden files
├── test-patterns-and-antipatterns.md ← AAA, isolation, anti-patterns phổ biến
└── interview-and-big-picture.md ← Big picture + câu hỏi phỏng vấn
Bức tranh tổng thể
E2E Tests
/ \
/ Slow, \
/ Expensive \
/_______________\
/ \
/ Integration \
/ Tests \
/ (DB, HTTP, Queue) \
/________________________\
/ \
/ Unit Tests \
/ Fast, Cheap, Isolated \
/________________________________\
Confidence ◄──────────────────►
Speed ◄──────────────────► (ngược lại)
Cost ◄──────────────────► (ngược lại)
Testing pyramid: nhiều unit test ở đáy (nhanh, rẻ), ít E2E ở đỉnh (chậm, đắt). Đây không phải quy tắc cứng — mà là heuristic để cân bằng confidence vs cost.
Các loại test trong Go ecosystem
| Loại | Tool | Mục đích | Speed |
|---|---|---|---|
| Unit | testing, testify |
Logic thuần, không side effects | < 1ms |
| Integration | testcontainers-go |
Code + real infra (DB, Redis) | 1-10s |
| Contract | pact-go |
API contract giữa services | 1-5s |
| E2E | playwright, httptest |
Full user journey | 10s-1min |
| Performance | testing.B, k6 |
Throughput, latency | Minutes |
| Property-based | gopter, rapid |
Fuzzing logic với random input | Variable |
Nguyên tắc cốt lõi
1. Test behavior, không phải implementation
// Sai: test internal state
assert.Equal(t, user.internalCache["key"], value)
// Đúng: test observable behavior
resp, _ := svc.GetUser(ctx, userID)
assert.Equal(t, "Alice", resp.Name)
2. Một test chỉ kiểm tra một điều
Khi test fail, bạn biết ngay lý do là gì. Test nhiều assertions phức tạp → khi fail, phải debug nhiều.
3. Test nên chạy được độc lập
Thứ tự test chạy không được ảnh hưởng kết quả. TestA không nên phụ thuộc state được tạo bởi TestB.
4. Fast feedback loop là tất cả
Unit test chạy trong milliseconds → dev chạy liên tục. E2E chạy 5 phút → dev chờ, mất tập trung, bỏ qua failures.
Quick Reference: Go Testing Commands
# Chạy tất cả tests
go test ./...
# Verbose output
go test -v ./...
# Chạy test cụ thể
go test -run TestUserService_GetUser ./internal/user/
# Với race detector (luôn bật trong CI)
go test -race ./...
# Coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
# Benchmark
go test -bench=. -benchmem ./...
# Short mode (skip long-running tests)
go test -short ./...
# Timeout
go test -timeout 30s ./...
Đọc theo thứ tự
testing-pyramid-and-strategy.md— nền tảng tư duymocks-stubs-fakes.md— toolbox cần thiếtintegration-and-contract.md— test với infra thậttest-patterns-and-antipatterns.md— làm đúng cáchinterview-and-big-picture.md— tổng hợp và luyện phỏng vấn