55 phútCơ bản
Bạn sẽ học được
  • Hiểu test pyramid và test trophy
  • Viết kiểm thử đơn vị bằng pytest và Vitest
  • Dùng test double hợp lý và tránh flaky test

Kiểm thử đơn vị là nền móng của mọi chiến lược kiểm thử tự động: nhanh, rẻ và chỉ rõ chỗ lỗi.

Kim tự tháp kiểm thử (Test Pyramid)

Mô hình quen thuộc: nhiều kiểm thử đơn vị (nhanh, rẻ) ở đáy, vừa phải kiểm thử tích hợp/API ở giữa, ít kiểm thử giao diện đầu-cuối (E2E, chậm, dễ chập chờn) ở đỉnh. Một biến thể được nhiều đội web dùng là "test trophy": dồn nhiều công sức vào kiểm thử tích hợp vì chúng bám sát hành vi người dùng hơn mà vẫn đủ nhanh. Dù chọn mô hình nào, nguyên tắc chung là: kiểm thử càng gần mã nguồn thì càng nhanh và dễ tìm nguyên nhân lỗi.

Kiểm thử đơn vị với pytest (Python)

Một kiểm thử tốt theo mẫu Arrange – Act – Assert (chuẩn bị – thực hiện – kiểm tra):

# gio_hang.py
class GioHang:
    def __init__(self):
        self.items = {}

    def them(self, ten, gia, sl=1):
        if gia < 0 or sl <= 0:
            raise ValueError("gia/sl khong hop le")
        self.items[ten] = (gia, self.items.get(ten, (gia, 0))[1] + sl)

    def tong(self):
        return sum(g * s for g, s in self.items.values())

# test_gio_hang.py
import pytest
from gio_hang import GioHang

def test_tong_tien():
    gh = GioHang()                # Arrange
    gh.them("But", 5000, 2)       # Act
    gh.them("Vo", 12000)
    assert gh.tong() == 22000     # Assert

def test_so_luong_am_bi_tu_choi():
    with pytest.raises(ValueError):
        GioHang().them("But", 5000, -1)

Chạy pytest -q. Thêm --cov=. (cần cài pytest-cov) để xem độ phủ.

Kiểm thử đơn vị với Vitest (JavaScript/TypeScript)

Vitest tương thích cú pháp Jest, chạy nhanh và dùng tốt cùng Vite, React, Vue, Next.js:

// tong.test.js
import { describe, it, expect } from 'vitest';
import { tinhTong } from './tong.js';

describe('tinhTong', () => {
  it('cộng đúng các phần tử', () => {
    expect(tinhTong([1, 2, 3])).toBe(6);
  });
  it('mảng rỗng trả về 0', () => {
    expect(tinhTong([])).toBe(0);
  });
});

Chạy bằng npx vitest (chế độ theo dõi, tự chạy lại khi lưu file).

Test double: stub, mock, fake

Khi mã gọi đến thứ khó kiểm soát (mạng, email, thời gian), hãy thay bằng test double: stub trả dữ liệu cố định, mock kiểm tra việc nó được gọi đúng cách, fake là bản cài đặt đơn giản (ví dụ CSDL trong bộ nhớ). Đừng mock quá tay: nếu kiểm thử chỉ kiểm chứng các mock, nó không còn chứng minh được gì về hệ thống thật.

Mẹo hay

Đặt tên kiểm thử như một câu mô tả hành vi: test_so_luong_am_bi_tu_choi đọc là hiểu ngay lỗi nằm ở đâu khi nó đỏ. Mỗi kiểm thử nên kiểm tra một điều và độc lập với các kiểm thử khác.

Kiểm thử hồi quy và flaky test

Mỗi lần sửa lỗi, hãy thêm một kiểm thử tái hiện lỗi đó – đó là kiểm thử hồi quy. Kiểm thử lúc đạt lúc không (flaky) phá hỏng niềm tin vào bộ kiểm thử; nguyên nhân thường gặp là phụ thuộc thứ tự, dữ liệu chung, thời gian/đồng hồ và chờ cố định (sleep). Hãy cô lập, sửa hoặc tạm loại khỏi pipeline chứ đừng "chạy lại cho qua".

Thực hành
  1. Cài pytest, chép lớp GioHang và hai kiểm thử ở trên, chạy với --cov rồi bổ sung ca còn thiếu.
  2. Viết thêm kiểm thử cho giá âm và thêm cùng một sản phẩm hai lần.
  3. Tìm một kiểm thử phụ thuộc thời gian hiện tại và viết lại bằng cách truyền thời gian vào hàm.
Tóm tắt bài học

Bạn đã nắm test pyramid/trophy, mẫu Arrange–Act–Assert, cách viết kiểm thử với pytest và Vitest, test double và cách xử lý flaky test.