Viết kiểm thử hồi quy từ bug report bằng AI cho dự án Python
Biến mô tả lỗi thành test có thể chạy được thay vì một ticket dễ bị quên. Playbook này dùng AI để phác thảo regression test, rồi kiểm chứng chặt bằng unittest hoặc pytest.
Một bug report kiểu “hàm xử lý chuỗi bị lỗi khi tham số phân cách không phải chuỗi” rất dễ đi theo vòng đời quen thuộc: sửa code, review, merge — rồi vài lần refactor sau lỗi quay lại. Ticket đã đóng, nhưng hành vi cần bảo vệ chưa hề được mã hóa.
AI coding assistant có thể rút ngắn đoạn khó nhất: chuyển ngôn ngữ mơ hồ của bug report thành giả thuyết kiểm thử. Nhưng AI không thể tự biết đâu là contract thật của hệ thống. Cách an toàn là để AI viết bản nháp test, còn developer dùng runner và review để xác nhận test thực sự bắt được lỗi.
Biến “đã sửa lỗi” thành hành vi được bảo vệ
Regression test là kiểm thử được thêm vào để lỗi cũ không lặng lẽ xuất hiện lại. Mục tiêu không phải tăng số lượng test, mà là ghi lại một hành vi quan sát được:
Input nào từng gây lỗi?
Kết quả đúng là giá trị nào, hay phải phát sinh exception nào?
Test chỉ cần một hàm độc lập, hay cần fixture để chuẩn bị dữ liệu?
Test sẽ chạy bằng runner nào trong CI?
unittest là framework unit test có sẵn trong Python standard library. Framework này tổ chức test qua TestCase, test suite và test runner; setUp() và tearDown() dùng cho bước chuẩn bị, dọn dẹp trước và sau mỗi test.
pytest là framework bên thứ ba, hỗ trợ assert thông thường, tự khám phá test và có thể chạy test suite viết bằng unittest.
> AI hữu ích nhất khi đề xuất case biên, tên test và assertion. Quyết định “đây có phải hành vi đúng không?” vẫn thuộc về người hiểu codebase và yêu cầu sản phẩm.
Chuẩn hóa bug report trước khi đưa cho AI
Đừng dán cả cuộc thảo luận dài rồi yêu cầu “viết test”. Hãy đóng gói bug report thành đầu vào có thể kiểm chứng, tách rõ sự kiện đã quan sát, hành vi mong muốn và điều chưa rõ.
Dùng mẫu sau với AI assistant mà đội bạn đang dùng:
text
Bạn là reviewer kiểm thử Python.
Bug report:
<dán mô tả lỗi, stack trace đã loại dữ liệu nhạy cảm>
Mã nguồn liên quan:
<dán hàm hoặc class cần kiểm thử>
Hành vi mong muốn đã được xác nhận:
<giá trị trả về, exception, hoặc side effect>
Test framework đang dùng:
<unittest hoặc pytest>
Hãy:
Tóm tắt input gây lỗi và oracle kiểm thử.
Đề xuất một regression test nhỏ nhất.
Nêu các giả định chưa được xác nhận, không tự bịa API.
Chỉ dùng public behavior; không kiểm tra chi tiết implementation.
Nếu thiếu thông tin để assert, hỏi lại thay vì đoán.
Oracle kiểm thử là tiêu chí xác định pass hay fail, chẳng hạn “hàm phải trả về danh sách” hoặc “phải phát sinh TypeError”. Nếu bug report chỉ nói “đã crash”, AI chưa có đủ dữ liệu để tự chọn đúng exception hoặc kết quả thay thế.
Với code độc quyền, hãy loại token, thông tin khách hàng, URL nội bộ và dữ liệu production trước khi gửi sang dịch vụ AI. Tài liệu pytest không quy định API AI, SDK AI, chi phí hay giới hạn sử dụng; những phần này phụ thuộc công cụ assistant của đội bạn.
Walkthrough: từ lỗi separator sai kiểu đến unittest
Xét một case nhỏ với oracle rõ ràng: gọi split() với separator không phải chuỗi phải phát sinh TypeError. Đây là loại yêu cầu đủ cụ thể để AI tạo bản nháp, sau đó developer kiểm tra lại bằng API chuẩn của Python.
Bạn có thể yêu cầu AI:
text
Viết một regression test unittest cho hành vi sau:
gọi split với separator không phải string phải ném TypeError.
Yêu cầu:
Kế thừa unittest.TestCase.
Tên method bắt đầu bằng test.
Dùng assertRaises.
Không thêm fixture nếu test không cần.
Một kết quả phù hợp với cấu trúc ví dụ chính thức của unittest là:
python
import unittest
class TestStringMethods(unittest.TestCase):
def testsplit(self):
s = "hello world"
self.assertEqual(s.split(), ["hello", "world"])
with self.assertRaises(TypeError):
s.split(2)
if name == "main":
unittest.main()
Phần cốt lõi là:
python
with self.assertRaises(TypeError):
s.split(2)
Khối này biến kỳ vọng “phải lỗi đúng kiểu” thành assertion thực thi được. unittest nhận diện các method có tên bắt đầu bằng test; các assertion như assertEqual(), assertTrue() và assertRaises() giúp runner thu thập kết quả, rồi tạo báo cáo cho toàn bộ lượt chạy.
Khi dự án dùng pytest
pytest có thể chạy test suite viết bằng unittest. Với test function thuần, framework này cho phép dùng assert thông thường và cung cấp thông tin chi tiết khi assertion thất bại.
README của pytest minh họa điều đó bằng một test cố ý thất bại:
python
def inc(x):
return x + 1
def testanswer():
assert inc(3) == 5
Vì inc(3) trả về 4, pytest hiển thị biểu thức lỗi cùng giá trị thực tế và kỳ vọng. Đây là minh họa cho khả năng assertion introspection, không phải mẫu regression test cần sao chép nguyên trạng.
Theo README, pytest hỗ trợ Python 3.10+ hoặc PyPy3, có cơ chế tự khám phá test, fixture theo mô-đun và kiến trúc plugin. Dự án được phát hành theo giấy phép MIT.
Chạy đúng test trước khi mở pull request
Với pytest, chạy:
text
pytest
Runner sẽ thu thập test và báo kết quả pass hoặc fail.
Với unittest, tài liệu hỗ trợ chạy test theo module, class hoặc method riêng. Bạn cũng có thể chỉ định file test theo đường dẫn nếu file vẫn import được như một module. Khi cần output chi tiết hơn, dùng tùy chọn -v.
Một quy trình kiểm chứng thực tế nên có ba lượt:
Xác nhận test fail khi bug còn tồn tại. Nếu test luôn xanh, assertion có thể chưa chạm vào bug.
Áp dụng bản sửa rồi chạy lại. Test phải xanh khi hành vi mong muốn đã được đáp ứng.
Chạy cả suite liên quan. Regression test mới không nên vô tình phá vỡ giả định cũ.
AI thường bỏ sót lượt đầu tiên. Nó có thể tạo test trông hợp lý nhưng chỉ kiểm tra implementation hiện tại, thay vì tái tạo lỗi. Đừng merge test do AI sinh ra chỉ vì nó đang pass.
Review bản nháp AI bằng checklist
Trước khi chấp nhận patch, rà lại:
[ ] Test mô tả một bug cụ thể, không kiểm tra chung chung.
[ ] Input tái tạo lỗi được tối giản nhưng vẫn giữ đúng bản chất.
[ ] Assertion kiểm tra public behavior, không khóa chặt private method.
[ ] Exception hoặc kết quả kỳ vọng đã được xác nhận.
[ ] Tên test bắt đầu bằng test nếu dùng unittest.
[ ] Test fail ở phiên bản có lỗi và pass sau bản sửa.
[ ] Dữ liệu gửi vào AI đã loại bí mật và thông tin production.
unittest phù hợp khi repository đã dùng standard library hoặc cần cấu trúc TestCase rõ ràng. pytest phù hợp với đội thích assert thông thường, tự khám phá test và hệ plugin.
Dù chọn runner nào, nguyên tắc không đổi: bug report chỉ trở thành regression test có giá trị khi assertion chứng minh được một contract mà đội ngũ thực sự muốn bảo vệ.
AI giúp bạn viết nhanh hơn; runner và review mới giúp test đáng tin hơn.