Cisco thử refactor legacy code với AI: QA cần dựng safety net
Cisco giao một kỹ sư thử chứng minh hướng refactor legacy code với AI, hướng tới mục tiêu refactor 98% mã legacy trong 24 tháng. Với QA, trọng tâm là khóa hành vi hiện có bằng characterization test, contract test và review thay đổi.
Một bản refactor do AI tạo ra có thể rất thuyết phục trong pull request: tên hàm rõ hơn, cấu trúc hiện đại hơn, ít đoạn lặp hơn. Nhưng nếu nút “Lưu” gửi sai dữ liệu, hoặc API đổi mã lỗi mà hệ thống khác đang phụ thuộc, đó vẫn là một thay đổi thất bại.
Câu chuyện Cisco đang thử là lời nhắc đáng chú ý cho QA. Jeetu Patel, chủ tịch kiêm giám đốc sản phẩm của Cisco, nói với Fortune rằng ông đã cấp token AI không giới hạn cho kỹ sư Padmanabhan Krishnamurthy để refactor code. Krishnamurthy có bốn tuần để chứng minh hướng đi; mục tiêu cuối cùng Patel nêu là refactor 98% mã legacy trong 24 tháng.
Với tester và QA engineer, chi tiết quan trọng không phải là số token. Câu hỏi lớn hơn là:
> Làm sao chứng minh code mới vẫn giữ đúng những hành vi quan trọng của code cũ?
Viết lại nhanh không đồng nghĩa giữ đúng hành vi
Theo bài báo, Krishnamurthy cho rằng một nhóm hai người có thể viết lại code legacy với hỗ trợ từ AI. Trong phần thảo luận cộng đồng, có ý kiến đặt câu hỏi về lý do cần refactor tới 98% mã legacy; những ý kiến khác lo rằng AI có thể tái tạo cả bug, lỗ hổng hoặc quyết định thiết kế cũ.
Một nhận xét lặp lại trong thảo luận là: tạo code mới có thể dễ hơn xác thực hành vi trong môi trường thực tế.
Đó là điểm QA cần tập trung. Legacy code không chỉ chứa nợ kỹ thuật. Nó thường giữ những quy tắc nghiệp vụ chưa từng được ghi đầy đủ trong tài liệu, chẳng hạn:
Trường để trống có thể nghĩa là “giữ giá trị cũ”, không phải null.
Ứng dụng tích hợp có thể bắt một mã lỗi hoặc cấu trúc lỗi cụ thể.
Một bước xử lý tưởng như thừa có thể là workaround cho hệ thống cũ.
Một luồng UI có thể phụ thuộc thứ tự thao tác của người dùng.
AI có thể giúp tạo phương án refactor nhanh hơn. Nhưng AI không tự biết hành vi nào phải được giữ nguyên nếu đội ngũ chưa biến chúng thành test, contract và tiêu chí review rõ ràng.
Vì vậy, QA không nên chỉ nhận ticket “test bản rewrite” vào cuối sprint. QA cần tham gia từ lúc đội kỹ thuật xác định phạm vi thay đổi.
Safety net đầu tiên: characterization test
Characterization test là test ghi nhận hành vi hiện tại của hệ thống trước khi thay đổi.
Nó không trả lời “hệ thống lý tưởng nên hoạt động thế nào”. Nó trả lời: với input này, phiên bản hiện tại đang làm gì?
Cách tiếp cận này đặc biệt hữu ích khi:
tài liệu legacy thiếu hoặc đã lỗi thời;
người viết code ban đầu không còn trong đội;
logic có nhiều ngoại lệ khó giải thích;
đội ngũ chưa thống nhất hành vi nào là business rule, hành vi nào là bug.
QA nên làm gì trước khi refactor?
Chọn luồng rủi ro cao
Ưu tiên phân quyền, đồng bộ dữ liệu, import/export, API tích hợp, logic tính toán quan trọng và các lỗi từng tái diễn.
Thu thập cả happy path lẫn case khó
Đừng chỉ test dữ liệu hợp lệ. Hãy xét dữ liệu thiếu trường, ký tự đặc biệt, trạng thái chuyển tiếp, request lặp, dữ liệu cũ và lỗi từ dependency.
Ghi nhận output có thể quan sát
Output không chỉ là giá trị trả về. Nó có thể gồm:
HTTP status, header và body;
dữ liệu được tạo hoặc cập nhật;
audit event hoặc log cần thiết;
thông báo hiển thị;
request gửi tới dịch vụ khác;
hành vi khi retry hoặc dependency lỗi.
Đóng băng hành vi bằng automation
Với UI, Playwright hoặc Selenium có thể bảo vệ các flow quan trọng. Với service, pytest hoặc framework API test phù hợp nên kiểm tra cả response lẫn side effect.
Không phải mọi hành vi cũ đều đáng giữ. Nếu phát hiện hành vi sai, QA nên mở bug hoặc ghi nhận quyết định rõ ràng: đây là thay đổi có chủ đích, không phải regression bị “hợp thức hóa” bằng test.
Dùng AI để hỗ trợ phân tích test, không thay thế bằng chứng
QA có thể yêu cầu AI hỗ trợ cấu trúc hóa các case đã quan sát:
text
Bạn là trợ lý phân tích test cho một hệ thống legacy.
Bối cảnh nghiệp vụ:
<motachucnang>
Đây là các input/output quan sát từ phiên bản hiện tại:
<danhsachcase>
Hãy tạo:
bảng characterization test;
phân loại happy path, boundary, invalid input, integration failure;
các side effect cần kiểm tra;
câu hỏi còn thiếu để phân biệt bug cũ với business rule hợp lệ.
Không tự suy đoán yêu cầu chưa có bằng chứng.
Đánh dấu rõ mỗi giả định.
Kết quả từ AI vẫn cần QA kiểm tra: case nào bị bỏ sót, AI có tự kết luận một hành vi “vô lý” là bug hay không, và expected result có đúng với quan sát thực tế không.
Contract test: khóa điểm tiếp giáp trước khi đổi phần bên trong
Nếu characterization test bảo vệ hành vi của một luồng, contract test bảo vệ giao kèo giữa các thành phần.
Contract có thể là:
schema request/response API;
event message;
quy tắc xác thực;
mã lỗi;
kiểu dữ liệu;
field bắt buộc;
dữ liệu gửi giữa các service.
Một bản refactor có thể không làm thay đổi UI nhưng vẫn phá contract ngầm. Ví dụ, endpoint vẫn trả JSON hợp lệ nhưng đã đổi tên field, bỏ field rỗng, đổi kiểu dữ liệu hoặc thay format lỗi. Consumer đang chạy ổn có thể hỏng ngay sau khi deploy.
Ví dụ: biến hành vi thành safety net
Giả sử chức năng legacy cập nhật hồ sơ người dùng:
> Hệ thống nhận tên hiển thị và email. Nếu email không hợp lệ, hồ sơ không được cập nhật. Nếu thành công, hệ thống trả về hồ sơ sau cập nhật.
Trước khi refactor, QA có thể tạo các kiểm tra:
Cập nhật tên và email hợp lệ: response trả dữ liệu mới, dữ liệu được lưu đúng.
Email thiếu: response giữ format lỗi hiện tại, dữ liệu cũ không đổi.
Email sai định dạng: không có cập nhật một phần.
Gửi lại cùng request: ghi nhận hành vi thực tế hiện tại rồi đưa vào characterization test.
Consumer phụ thuộc response: kiểm tra field bắt buộc, kiểu dữ liệu và mã lỗi mà consumer đang dùng.
AI có thể hỗ trợ rà soát độ phủ từ contract đã có:
text
Hãy đọc contract API dưới đây và tạo checklist regression
cho bản refactor nội bộ.
Contract hiện tại:
<requestschema>
<responseschema>
<errorexamples>
Yêu cầu:
Không đề xuất thay đổi contract.
Liệt kê assertion cho status, header, schema, field bắt buộc,
kiểu dữ liệu, error format và side effect.
Chỉ ra trường hợp consumer có thể hỏng dù response vẫn là JSON hợp lệ.
Kết quả hữu ích không nhất thiết là danh sách test dài. Nó phải chỉ ra assertion cụ thể, như:
field vẫn tồn tại;
dữ liệu không đổi khi request lỗi;
error body vẫn có cấu trúc mà consumer đang parse;
request thất bại không phát sinh side effect ngoài ý muốn.
Review diff: QA đừng chỉ nhìn màn hình cuối cùng
Với AI-generated refactor, diff có thể rất lớn và gây khó cho reviewer. QA nên đề nghị chia thay đổi theo hành vi hoặc module thay vì gộp thành một pull request khổng lồ.
Khi review, hãy đặt các câu hỏi:
Nhánh điều kiện nào bị xóa, gộp hoặc đảo chiều?
Default value, timeout, retry hoặc thứ tự xử lý có đổi không?
Validation có chuyển vị trí trước hoặc sau khi gọi dependency không?
Query, mapping dữ liệu hoặc serialization có đổi không?
Error handling có chuyển từ trả lỗi rõ ràng sang nuốt lỗi không?
Selector UI có bị thay bằng selector dễ vỡ không?
Với Playwright hoặc Selenium, cần đặc biệt lưu ý selector phụ thuộc text, CSS động hoặc cấu trúc layout. Nên ưu tiên locator ổn định do sản phẩm cung cấp và kiểm tra test có phụ thuộc timing hay không.
Một diff “đẹp” không chứng minh được tính tương đương về hành vi. Nhưng diff nhỏ, phạm vi rõ và được liên kết với test case cụ thể sẽ giúp QA khoanh vùng regression nhanh hơn.
Không đưa dữ liệu production vào prompt
Khi nhờ AI phân tích code, log hoặc test failure, không dán dữ liệu production, token, API key, mật khẩu, session cookie hay thông tin định danh khách hàng vào công cụ AI không được tổ chức cho phép.
Thay vào đó:
thay giá trị thật bằng placeholder;
chỉ giữ phần log cần tái hiện lỗi;
dùng dữ liệu test đã làm sạch;
kiểm tra chính sách nội bộ trước khi tải source code hoặc log lên công cụ AI.
Câu chuyện tại Cisco mới là một mục tiêu và thử nghiệm được lãnh đạo công ty mô tả; kết quả chưa được kiểm chứng độc lập. Dù AI được cấp bao nhiêu token, QA vẫn là lớp bảo vệ biến một bản refactor “trông hiện đại” thành thay đổi đáng tin cậy.
Checklist trước khi sign-off bản refactor
[ ] Có characterization test cho các hành vi quan trọng của code cũ.
[ ] Đã phân biệt rõ bug cần sửa và hành vi phải giữ.
[ ] API, event và tích hợp quan trọng có contract test.
[ ] Test kiểm tra side effect, không chỉ response hoặc UI.
[ ] Diff được chia nhỏ và liên kết với phạm vi test cụ thể.
[ ] AI output đã được rà soát về expected result, coverage gap và selector dễ flaky.
[ ] Không có dữ liệu production hoặc credentials trong prompt.
Bản refactor đáng tin không phải là bản được AI tạo ra nhanh nhất. Đó là bản có safety net đủ tốt để đội ngũ biết chính xác điều gì đã thay đổi — và điều gì tuyệt đối không được phép thay đổi.