Vì sao phải viết test?
Test không phải “thêm việc” mà là “tiết kiệm việc”. Mỗi lần sửa code, chạy test 2 giây biết ngay có phá gì không. Không test thì phải bấm tay kiểm tra lại toàn bộ — mỗi lần mất 30 phút.
| Loại test | Kiểm tra gì | Tốc độ | Số lượng |
|---|---|---|---|
| Unit test | Từng hàm riêng lẻ | ⚡ Rất nhanh (ms) | Nhiều nhất |
| Integration test | Nhiều module ghép lại | 🏃 Vừa (giây) | Vừa |
| E2E test | Toàn bộ app như user thật | 🐢 Chậm (phút) | Ít nhất |
Viết unit test đầu tiên
// File: math.js
// Module cần test
export function add(a, b) { return a + b }
export function divide(a, b) {
if (b === 0) throw new Error("Không chia được cho 0")
return a / b
}
// File: math.test.js
import { describe, it, expect } from 'vitest'
import { add, divide } from './math'
describe('add', () => {
it('cộng 2 số dương', () => {
// Arrange: chuẩn bị dữ liệu
const a = 2, b = 3
// Act: chạy hàm cần test
const result = add(a, b)
// Assert: kiểm tra kết quả
expect(result).toBe(5)
})
it('cộng số âm', () => {
expect(add(-1, -2)).toBe(-3)
})
})
describe('divide', () => {
it('chia bình thường', () => {
expect(divide(10, 2)).toBe(5)
})
it('chia cho 0 phải throw error', () => {
expect(() => divide(10, 0)).toThrow('Không chia được cho 0')
})
})
Mỗi test case có 3 bước: Arrange (chuẩn bị dữ liệu), Act (chạy hàm), Assert (kiểm tra kết quả). Theo thứ tự này giúp test dễ đọc và bảo trì.
Test cái gì, bỏ cái gì?
Test hành vi quan trọng: logic nghiệp vụ, edge case (input rỗng, số âm, null), error handling. KHÔNG test: thư viện bên thứ 3 (họ đã test rồi), getter/setter đơn giản, CSS/layout.
❓ Trong AAA pattern, "Assert" làm gì?
- Cài đặt và chạy Vitest
- Viết test theo AAA pattern
- Test edge case và error
- Biết test hành vi quan trọng, bỏ trivial code