Mã tốt là mã được kiểm thử và nhất quán. Bài này hướng dẫn viết kiểm thử tự động với Vitest (và node:test), cùng ESLint, Prettier để giữ chất lượng mã.
- Hiểu kim tự tháp kiểm thử
- Viết unit test với Vitest
- Kiểm thử hàm bất đồng bộ và dùng mock
- Cấu hình ESLint, Prettier
- Unit test
- Kiểm tra một đơn vị mã nhỏ, độc lập.
- Assertion
- Câu khẳng định kết quả mong đợi: expect(x).toBe(y).
- Mock
- Đối tượng giả thay thế phụ thuộc thật.
- Linter
- Công cụ phát hiện lỗi tiềm ẩn và vi phạm quy ước.
Khái niệm và lý thuyết
Kim tự tháp kiểm thử: nhiều unit test (nhanh, rẻ), ít hơn integration test (nhiều mô-đun cùng nhau), ít end-to-end test (mô phỏng người dùng thật bằng Playwright). Mỗi test theo mẫu AAA: Arrange (chuẩn bị), Act (thực hiện), Assert (kiểm tra).
Kiểm thử không chỉ tìm lỗi mà còn là lưới an toàn khi sửa mã: chạy lại test để chắc chắn không làm hỏng chức năng cũ.
Vitest
npm install -D vitest// tien.js
export const dinhDangTien = n => n.toLocaleString("vi-VN") + " đ";
export function tinhGiam(gia, phanTram) {
if (phanTram < 0 || phanTram > 100) throw new RangeError("Phần trăm không hợp lệ");
return Math.round(gia * (1 - phanTram / 100));
}
// tien.test.js
import { describe, it, expect } from "vitest";
import { dinhDangTien, tinhGiam } from "./tien.js";
describe("tinhGiam", () => {
it("giảm 20%", () => expect(tinhGiam(100000, 20)).toBe(80000));
it("báo lỗi khi > 100", () => expect(() => tinhGiam(1, 120)).toThrow(RangeError));
});
it("định dạng tiền", () => expect(dinhDangTien(1500000)).toBe("1.500.000 đ"));npx vitest # chế độ theo dõi
npx vitest run --coverageTest bất đồng bộ và mock
import { vi, it, expect } from "vitest";
import { layTenNguoiDung } from "./api.js";
it("lấy tên từ API", async () => {
globalThis.fetch = vi.fn().mockResolvedValue({
ok: true, json: async () => ({ name: "An" }) });
await expect(layTenNguoiDung(1)).resolves.toBe("An");
expect(fetch).toHaveBeenCalledOnce();
});ESLint và Prettier
npm init @eslint/config@latest
npm install -D prettier
npx eslint . && npx prettier --check .ESLint tìm lỗi (biến không dùng, so sánh sai); Prettier định dạng mã tự động. Bật “Format on Save” trong VS Code. Không cần cài gì, Node.js cũng có sẵn trình chạy test: import { test } from "node:test".
Viết test ngay khi sửa một lỗi: test tái hiện lỗi trước, rồi sửa mã cho test qua. Lỗi đó sẽ không bao giờ quay lại.
Test phụ thuộc thứ tự chạy hoặc dữ liệu thật trên mạng sẽ lúc qua lúc trượt (flaky). Dùng mock và dữ liệu cố định.
- Viết test cho hàm xếp loại học lực (biên 5, 6.5, 8).
- Viết test cho hàm có ném lỗi.
- Mock fetch để test hàm tải danh sách sản phẩm.
- Cấu hình ESLint + Prettier cho dự án Node ở Bài 14 và sửa hết cảnh báo.
- Nhiều unit test, ít E2E test.
- Vitest: describe, it, expect; vi.fn để mock.
- ESLint bắt lỗi, Prettier định dạng.
- Test là lưới an toàn khi sửa mã.