Phát triển hướng kiểm thử (TDD) trong vòng đời phát triển hướng AI (AI-DLC): tổng quan bằng chứng và đề xuất thực hành
Tóm tắt. Phát triển hướng kiểm thử (Test-Driven Development, TDD) là kỹ thuật lặp ba bước: viết một kiểm thử thất bại (Red), viết lượng mã tối thiểu để kiểm thử đó đạt (Green), rồi tái cấu trúc mã trong khi giữ toàn bộ kiểm thử đạt (Refactor). Các nghiên cứu thực nghiệm trước kỷ nguyên AI cho kết quả không đồng nhất: nghiên cứu tình huống trên bốn đội công nghiệp ghi nhận mật độ lỗi giảm 40–90% với chi phí thời gian ban đầu tăng 15–35%, trong khi phân tích tổng hợp 27 nghiên cứu chỉ thấy cải thiện nhỏ về chất lượng. Trong vòng đời phát triển hướng AI (AI-Driven Development Life Cycle, AI-DLC), nơi mã nguồn ngày càng do mô hình ngôn ngữ lớn (LLM) sinh ra, kiểm thử có thêm một chức năng: đóng vai trò đặc tả thực thi được, qua đó làm rõ ý định và kiểm chứng đầu ra của AI. Các nghiên cứu về sinh mã dẫn dắt bởi kiểm thử cho thấy mức cải thiện độ chính xác đáng kể, song đều thực hiện trên bài toán quy mô nhỏ; đồng thời chất lượng của chính bộ kiểm thử trở thành giới hạn của mọi kết luận về tính đúng đắn.
Từ khoá: TDD, AI-DLC, kiểm thử đơn vị, mô hình ngôn ngữ lớn, đặc tả thực thi được, tái cấu trúc.
1. Đặt vấn đề
Việc lập trình viên giao một phần ngày càng lớn công việc viết mã cho trợ lý AI (xem loạt bài AI-Driven Development) làm thay đổi câu hỏi trung tâm của kiểm thử. Trước đây, câu hỏi là "mã do con người viết có đúng không". Hiện nay, câu hỏi là "ai chịu trách nhiệm xác định thế nào là đúng, khi mã được sinh ra với tốc độ vượt khả năng đọc lại từng dòng".
TDD là ứng viên tự nhiên cho câu hỏi này, vì nó đặt định nghĩa của sự đúng đắn (kiểm thử) trước phần cài đặt. Tuy nhiên, các bằng chứng kinh điển về TDD được thu thập khi con người viết cả kiểm thử lẫn mã. Bài viết này nhằm trả lời ba câu hỏi:
- Bằng chứng thực nghiệm hiện có nói gì về hiệu quả của TDD?
- TDD có thể được đặt ở đâu trong AI-DLC, và các nghiên cứu về sinh mã bằng LLM hỗ trợ điều đó đến mức nào?
- Một quy trình thực hành khả thi trông như thế nào, và những rủi ro nào cần kiểm soát?
Phạm vi tài liệu gồm các công bố đã được đối chiếu với phần tóm tắt trên nguồn gốc; cách xử lý chi tiết ở mục 7.
2. Cơ sở lý thuyết
2.1. Vòng lặp TDD
Beck (2002), trong Test-Driven Development: By Example, mô tả TDD qua hai quy tắc: chỉ viết mã mới khi có một kiểm thử tự động đang thất bại, và loại bỏ sự trùng lặp. Hai quy tắc này tạo thành vòng lặp ba pha:
| Pha | Hoạt động | Điều kiện kết thúc |
|---|---|---|
| Red | Viết một kiểm thử mô tả hành vi mong muốn | Kiểm thử chạy và thất bại đúng nguyên nhân dự kiến |
| Green | Viết mã tối thiểu, có thể gán cứng kết quả | Toàn bộ kiểm thử đạt |
| Refactor | Cải thiện cấu trúc mã và kiểm thử, không đổi hành vi | Toàn bộ kiểm thử vẫn đạt |
Cần phân biệt TDD với ba khái niệm lân cận. Test-first chỉ quy định thứ tự viết kiểm thử trước; TDD bổ sung tái cấu trúc có kỷ luật và nhịp làm việc theo bước nhỏ. Kiểm thử đơn vị là sản phẩm, còn TDD là quy trình tạo ra sản phẩm đó và đồng thời định hình thiết kế. ATDD/BDD đặt kiểm thử ở mức hành vi nghiệp vụ, thường là vòng ngoài bao quanh vòng TDD ở mức đơn vị.
Một điều kiện dễ bị bỏ qua là pha Red phải thất bại đúng nguyên nhân. Kiểm thử đỏ do lỗi ngoại lệ trong chính mã kiểm thử không chứng minh được điều gì về hành vi cần xây dựng.
2.2. AI-DLC
AI-DLC do Raja SP (AWS) đề xuất, công bố ngày 31/07/2025. Phương pháp này chủ trương AI đóng vai trò chủ thể thực thi, còn con người giữ thẩm quyền ra quyết định ở các điểm cần ngữ cảnh nghiệp vụ và phán đoán, theo nguyên lý "AI Powered Execution with Human Oversight". Vòng đời gồm ba pha:
- Inception: AI chuyển ý định nghiệp vụ thành yêu cầu, câu chuyện người dùng và các đơn vị công việc thông qua hoạt động Mob Elaboration, trong đó nhóm liên chức năng thẩm định các đề xuất và câu hỏi của AI.
- Construction: AI đề xuất kiến trúc logic, mô hình miền, mã nguồn và bộ kiểm thử thông qua Mob Construction; nhóm làm rõ các quyết định kỹ thuật theo thời gian thực.
- Operations: AI quản lý hạ tầng dưới dạng mã và triển khai, dựa trên ngữ cảnh tích luỹ từ các pha trước.
Về thuật ngữ, Bolt thay cho sprint (chu kỳ tính bằng giờ hoặc ngày), và Unit of Work thay cho epic. Trong mô tả này, kiểm thử xuất hiện như một sản phẩm do AI sinh ra liên tục trong Construction. Tài liệu giới thiệu nói đến việc AI áp dụng chuẩn mã hoá, mẫu thiết k ế và yêu cầu bảo mật của tổ chức khi sinh bộ kiểm thử. Vì vậy, việc gắn TDD vào AI-DLC trong bài này là đề xuất của tác giả bài viết, không phải nội dung được quy định trong tài liệu gốc.
3. Bằng chứng thực nghiệm về TDD
Các nghiên cứu dưới đây khác nhau về đối tượng (sinh viên hay chuyên gia), thiết kế (thí nghiệm hay nghiên cứu tình huống) và thang đo, nên cần đọc như những lát cắt bổ sung cho nhau thay vì một con số duy nhất.
| Nghiên cứu | Loại hình | Kết quả chính |
|---|---|---|
| Nagappan, Maximilien, Bhat, Williams (2008) | Nghiên cứu tình huống, 4 đội (3 Microsoft, 1 IBM) | Mật độ lỗi trước phát hành giảm 40–90% so với dự án tương đương; thời gian phát triển ban đầu tăng 15–35% |
| Rafique & Mišić (2013) | Phân tích tổng hợp, 27 nghiên cứu | Cải thiện nhỏ về chất lượng ngoài, gần như không ảnh hưởng năng suất; nghiên cứu công nghiệp cho mức cải thiện chất lượng và mức sụt giảm năng suất đều lớn hơn nghiên cứu học thuật |
| Fucci và cộng sự (2017) | Thí nghiệm, 39 lập trình viên chuyên nghiệp | Thứ tự viết kiểm thử và mã không có ảnh hưởng quan trọng; chất lượng và năng suất gắn với độ mịn và tính đều đặn của các bước |
| Causevic, Sundmark, Punnekkat (2011) | Tổng quan hệ thống | Bảy yếu tố cản trở áp dụng, gồm tăng thời gian phát triển, thiếu kinh nghiệm TDD, thiếu thiết kế trước, vấn đề riêng của miền và công cụ, mã kế thừa |
Ba nhận xét rút ra từ bảng trên:
- Lợi ích về chất lượng đi kèm chi phí. Mức giảm lỗi 40–90% không tách rời khỏi mức tăng 15–35% thời gian ban đầu. Giá trị ròng phụ thuộc vào chi phí của lỗi trong môi trường cụ thể.
- Bối cảnh khuếch đại cả lợi ích lẫn chi phí. Phân tích của Rafique & Mišić cho thấy nghiên cứu công nghiệp có cả mức cải thiện chất lượng lẫn mức sụt giảm năng suất lớn hơn nghiên cứu học thuật. Mức sụt giảm năng suất cũng lớn hơn khi nhóm áp dụng TDD đầu tư công sức kiểm thử nhiều hơn đáng kể so với nhóm đối chứng.
- Cơ chế quan trọng hơn thứ tự. Fucci và cộng sự không tìm thấy ảnh hưởng quan trọng của việc viết kiểm thử trước hay sau; kết quả tốt gắn với bước nhỏ và đều. Các tác giả đề xuất lợi ích đến từ "những bước nhỏ, đều đặn giúp tập trung và giữ nhịp". Đây là điểm có ý nghĩa đặc biệt cho mục 4.
Karac & Turhan (2018) cũng xem xét TDD đã đáp ứng được bao nhiêu kỳ vọng đặt ra, nhấn mạnh rằng TDD không chỉ là viết kiểm thử trước. Bài viết này không trích dẫn kết luận định lượng của công bố đó.
4. TDD trong bối cảnh AI-DLC
4.1. Kiểm thử như đặc tả thực thi được
Khi mã do LLM sinh ra, một yêu cầu bằng ngôn ngữ tự nhiên thường chứa nhiều điểm mơ hồ mà mô hình sẽ giải quyết theo cách riêng của nó. Kiểm thử loại bỏ sự mơ hồ này bằng một phát biểu có thể chạy được. Một số nghiên cứu gần đây khảo sát hướng tiếp cận này:
| Nghiên cứu | Thiết kế | Kết quả chính |
|---|---|---|
| Fakhoury và cộng sự (2024), TiCoder, IEEE TSE | Quy trình tương tác dùng kiểm thử để làm rõ ý định; nghiên cứu người dùng với 15 lập trình viên; 4 LLM, 2 tập dữ liệu Python | Độ chính xác pass@1 tăng trung bình tuyệt đối 45,97% trong vòng 5 lần tương tác; tải nhận thức của người tham gia giảm có ý nghĩa |
| Liang và cộng sự (2026), ClassEval-TDD | Khung lặp theo TDD cho sinh mã mức lớp, 8 LLM | Độ đúng đắn tăng 12–26 điểm phần trăm so với sinh trực tiếp; tối đa 71% lớp đúng hoàn toàn |
| Piya & Sullivan (2023), LLM4TDD | ChatGPT trên bài toán LeetCode, đưa kiểm thử vào dần dần | Khảo sát ảnh hưởng của thuộc tính kiểm thử, câu lệnh gợi ý và bài toán; không trích số liệu cụ thể trong bài này |
Các kết quả cùng hướng: cung cấp kiểm thử cho mô hình, và cho phép mô hình lặp lại theo phản hồi, cải thiện đáng kể độ chính xác so với sinh trực tiếp từ mô tả. Cần lưu ý ba giới hạn. Thứ nhất, các thực nghiệm dùng bài toán chuẩn (hàm, lớp đơn lẻ), chưa phản ánh hệ thống nhiều thành phần. Thứ hai, "độ chính xác" ở đây được đo bằng chính các bộ kiểm thử, nên phụ thuộc chất lượng của chúng (xem 4.2). Thứ ba, mẫu người dùng của TiCoder nhỏ (15 người).
4.2. Chất lượng kiểm thử là giới hạn của tính đúng đắn
Liu và cộng sự (2023) với EvalPlus mở rộng bộ kiểm thử của HumanEval lên 80 lần và đánh giá lại 26 LLM. Tỷ lệ đạt giảm tới 19,3–28,9%, và thứ hạng giữa các mô hình thay đổi: hai mô hình mã nguồn mở vượt ChatGPT trên bộ kiểm thử mở rộng nhưng không vượt trên bộ gốc. Các tác giả kết luận sự thiếu hụt của kiểm thử có thể dẫn tới xếp hạng sai.
Kết quả này không thuộc về TDD thuần tuý, nhưng có hệ quả trực tiếp khi AI-DLC cho AI sinh cả mã lẫn kiểm thử. Nếu một mô hình viết kiểm thử dựa trên chính cách hiểu của nó về yêu cầu, rồi viết mã để đạt các kiểm thử đó, thì việc "tất cả kiểm thử đạt" chỉ chứng minh sự nhất quán nội bộ của mô hình, không chứng minh sự phù hợp với ý định nghiệp vụ. Đây là lập luận suy diễn của tác giả bài viết, chưa có nghiên cứu nào được tìm thấy đo trực tiếp hiện tượng này trong AI-DLC. Các rủi ro rộng hơn của việc giao mã cho AI được phân tích ở phần 3 của loạt bài AI-Driven Development; cách đưa tri thức kỹ thuật của dự án vào tác tử AI được bàn ở bài về agent skills.
4.3. Đề xuất phân vai
Từ hai nhận xét trên, bài viết đề xuất một nguyên tắc phân vai, đối chiếu với các pha AI-DLC:
| Pha AI-DLC | Hoạt động TDD tương ứng | Vai trò đề xuất |
|---|---|---|
| Inception (Mob Elaboration) | Chuyển tiêu chí chấp nhận thành ví dụ cụ thể và kiểm thử ở mức hành vi | AI soạn thảo, con người thẩm định vì đây là nơi ý định nghiệp vụ được cố định |
| Construction (Mob Construction), pha Red | Viết kiểm thử đơn vị mô tả hành vi tiếp theo | Con người viết hoặc phê duyệt từng kiểm thử trước khi AI viết mã |
| Construction, pha Green | Cài đặt tối thiểu để kiểm thử đạt | AI thực hiện; kết quả được kiểm chứng bằng kiểm thử, không bằng việc đọc lướt |
| Construction, pha Refactor | Tái cấu trúc khi toàn bộ kiểm thử đạt | AI đề xuất, con người xét duyệt; kiểm thử là lưới an toàn |
Cơ sở của việc đặt thẩm quyền ở pha Red: đó là nơi định nghĩa sự đúng đắn, tương ứng với nguyên lý thẩm quyền quyết định thuộc về con người của AI-DLC. Cơ sở của việc giao pha Green cho AI: đây là phần có phản hồi tự động rõ ràng nhất, đúng loại tác vụ mà các nghiên cứu ở 4.1 cho thấy mô hình xử lý tốt hơn khi có kiểm thử dẫn dắt.
Nhịp làm việc cũng tương thích. Fucci và cộng sự gắn kết quả tốt với bước nhỏ và đều, còn AI-DLC dùng Bolt (giờ hoặc ngày) thay cho sprint. Mỗi vòng Red-Green-Refactor có thể xem là đơn vị mịn hơn nằm trong một Bolt.
4.4. Khoảng trống nghiên cứu
Trong phạm vi tìm kiếm của tác giả, chưa thấy nghiên cứu nào đánh giá TDD gắn với AI-DLC ở quy mô dự án công nghiệp. Các kết quả ở 4.1 đến từ bài toán chuẩn; các kết quả ở mục 3 đến từ giai đoạn trước khi trợ lý AI phổ biến. Việc gộp hai nhóm bằng chứng để kết luận về quy trình kết hợp là một suy luận, cần được kiểm chứng.
5. Minh hoạ thực hành
Bài toán giả định, đủ nhỏ để theo dõi: đơn hàng từ 1.000.000 trở lên được giảm 10%; khách VIP được giảm thêm 5% cộng dồn; tổng tiền hàng âm là dữ liệu không hợp lệ. Theo phân vai ở 4.3, người phát triển viết kiểm thử, trợ lý AI đề xuất cài đặt.
5.1. Vòng 1: Red, rồi Green bằng cách giả lập
Kiểm thử đầu tiên chọn tình huống đơn giản nhất:
public class OrderPricingTests
{
[Fact]
public void Total_UnderThreshold_NoDiscount()
{
var pricing = new OrderPricing();
Assert.Equal(500_000m, pricing.Total(500_000m, isVip: false));
}
}
Lớp OrderPricing chưa tồn tại nên đoạn mã chưa biên dịch được, đây cũng là một dạng Red. Cần tạo lớp rỗng với phương thức ném NotImplementedException để kiểm thử chạy và thất bại đúng nguyên nhân, sau đó viết lượng mã đủ để đạt:
public class OrderPricing
{
public decimal Total(decimal subtotal, bool isVip) => subtotal;
}
Đây là kỹ thuật Fake It của Beck: trả về đúng giá trị kiểm thử cần, chưa tổng quát hoá. Với trợ lý AI, pha này đặc biệt quan trọng: người phát triển cần quan sát kiểm thử thật sự đỏ trước khi yêu cầu AI viết mã.
5.2. Vòng 2: tam giác hoá
Bổ sung kiểm thử buộc mã phải tính toán thật (triangulation):
[Fact]
public void Total_AtThreshold_Gets10PercentOff()
{
var pricing = new OrderPricing();
Assert.Equal(900_000m, pricing.Total(1_000_000m, isVip: false));
}
public decimal Total(decimal subtotal, bool isVip)
=> subtotal >= 1_000_000m ? subtotal * 0.90m : subtotal;
Giá trị biên (đúng bằng ngưỡng) là nơi lỗi > so với >= thường xuất hiện. Một trợ lý AI có thể chọn sai biên nếu yêu cầu chỉ được mô tả bằng lời; kiểm thử biên loại bỏ khả năng này.
5.3. Vòng 3: VIP, dữ liệu không hợp lệ và tái cấu trúc
[Fact]
public void Total_VipUnderThreshold_Gets5PercentOff()
{
var pricing = new OrderPricing();
Assert.Equal(475_000m, pricing.Total(500_000m, isVip: true));
}
[Fact]
public void Total_VipAtThreshold_StacksTo15Percent()
{
var pricing = new OrderPricing();
Assert.Equal(850_000m, pricing.Total(1_000_000m, isVip: true));
}
[Fact]
public void Total_NegativeSubtotal_Throws()
{
var pricing = new OrderPricing();
Assert.Throws<ArgumentOutOfRangeException>(
() => pricing.Total(-1m, isVip: false));
}
Khi toàn bộ kiểm thử đạt, pha Refactor loại bỏ điều kiện lồng nhau và đặt tên cho các hằng số nghiệp vụ:
public class OrderPricing
{
const decimal BulkThreshold = 1_000_000m;
const decimal BulkRate = 0.10m;
const decimal VipRate = 0.05m;
public decimal Total(decimal subtotal, bool isVip)
{
if (subtotal < 0)
throw new ArgumentOutOfRangeException(nameof(subtotal));
var rate = 0m;
if (subtotal >= BulkThreshold) rate += BulkRate;
if (isVip) rate += VipRate;
return subtotal * (1 - rate);
}
}
Quy tắc cộng dồn nay nằm ở một vị trí. Nếu về sau mô hình hoặc con ngư ời đổi sang giảm giá nhân dồn, kiểm thử StacksTo15Percent sẽ thất bại ngay. Đây là chức năng "lưới an toàn" của bộ kiểm thử, và càng quan trọng khi mã được thay đổi hàng loạt bởi AI.
Ghi chú kiểm chứng. Các giá trị kỳ vọng (475.000; 850.000; 900.000) được tính tay theo quy tắc. Mã C# trong bài chưa được biên dịch và chạy khi biên soạn. Cần chạy
dotnet testtrước khi sử dụng.
5.4. Các sai lệch thường gặp
- Viết nhiều kiểm thử cùng lúc rồi mới yêu cầu mã. Mất vòng phản hồi ngắn, vốn là yếu tố được gắn với kết quả tốt (Fucci và cộng sự, 2017). Với AI, rủi ro tăng vì mô hình dễ sinh ra một khối lớn mã khó thẩm định.
- Bỏ qua Refactor. Chỉ thực hiện Red-Green tạo ra mã chạy được nhưng thiếu cấu trúc, và kiểm thử dần trở thành gánh nặng bảo trì.
- Kiểm thử bám vào cài đặt thay vì hành vi quan sát được. Thay đổi cài đặt làm vỡ kiểm thử dù hành vi không đổi.
- Để AI viết cả kiểm thử lẫn mã mà không thẩm định kiểm thử (xem 4.2).