Khi dùng tốt, AI rất giỏi ở phần liệt kê của việc test — nó brainstorm các edge case và viết boilerplate nhanh chóng. Nhưng bạn phải kiểm chứng rằng các assertion có ý nghĩa, vì AI sẵn sàng viết những test pass mà không chứng minh được điều gì.
Khi dùng tốt, AI rất giỏi ở phần liệt kê của việc test — nó brainstorm các edge case và viết boilerplate nhanh chóng. Nhưng bạn phải kiểm chứng rằng các assertion có ý nghĩa, vì AI sẵn sàng viết những test pass mà không chứng minh được điều gì.
// Hàm cần test, kèm contract của nó:
// applyDiscount(price, percent) -> price giảm theo percent.
// Contract: percent phải là 0..100; ném RangeError nếu khác. price >= 0.
function applyDiscount(price, percent) {
if (percent < 0 || percent > 100) throw new RangeError('percent out of range');
return price - (price * percent) / 100;
}
// Các test case do AI đề xuất (Jest) — chú ý đường biên và đường lỗi, không chỉ happy path:
test('applies a normal discount', () => {
expect(applyDiscount(100, 20)).toBe(80); // happy path
});
test('0% leaves price unchanged', () => {
expect(applyDiscount(100, 0)).toBe(100); // biên: cạnh dưới
});
test('100% makes it free', () => {
expect(applyDiscount(100, 100)).toBe(0); // biên: cạnh trên
});
test('rejects percent above 100', () => {
expect(() => applyDiscount(100, 150)).toThrow(RangeError); // đường lỗi
});
AI đã đề xuất các trường hợp biên (0 và 100) và đường lỗi mà bạn có thể quên. Việc của bạn là xác nhận toBe(80) là giá trị mong đợi đúng, không chỉ là bất cứ thứ gì hàm tình cờ trả về.
Phần khó của việc test không phải là gõ các khối test(...) — mà là nghĩ ra những trường hợp bạn vốn sẽ bỏ sót, và AI thực sự giỏi ở độ rộng đó. Nhưng nó không biết code của bạn đáng lẽ phải làm gì trừ khi bạn nói cho nó, nên nếu không kiểm soát nó có xu hướng viết những test phản chiếu phần triển khai (chúng pass, nhưng chúng vẫn pass kể cả khi hàm sai). Coi AI như một bộ sinh edge-case trong khi bạn làm chủ các assertion mang lại cho bạn độ phủ rộng và tính đúng đắn thực sự — tốc độ từ AI, phán đoán từ bạn.