Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 1 — Tại sao cần agent sinh test và agent khác script sinh test ra sao

Đã đọc 0/8 mục · còn khoảng 4 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Tại sao cần agent sinh test và agent khác script sinh test ra sao

Viết test là việc ai cũng biết là quan trọng nhưng ai cũng ngại làm. Một hàm calculate_discount() có thể mất 5 phút để viết nhưng 30 phút để test cho đủ các nhánh. Đó là lý do coverage của phần lớn dự án nằm dưới 40%. Một agent sinh test không phải là công cụ magic thay bạn tư duy, mà là một vòng lặp tự động: đọc code → sinh test → chạy test → đọc kết quả → sửa test → lặp lại cho đến khi đạt mục tiêu.

Agent khác gì so với script hoặc prompt một lần

Rất nhiều người nhầm "gọi LLM sinh test" là đã có agent. Không phải. Sự khác biệt nằm ở vòng lặp có phản hồi (feedback loop):

  • Prompt một lần: bạn dán code, LLM trả về test, bạn tự chạy. Nếu test sai import, sai assertion, bạn tự sửa.
  • Agent: hệ thống tự chạy test vừa sinh, đọc lỗi (traceback, assertion fail, coverage report), và tự vòng lại để sửa cho đến khi test thực sự pass và đo được.
Sự khác biệt này quyết định giá trị. Một test do LLM sinh mà không chạy được thì vô dụng — thậm chí nguy hiểm vì tạo ảo giác "đã có test".

Kiến trúc tối thiểu của một agent sinh test

[Đọc code + context] 
      ↓
[LLM sinh test]
      ↓
[Chạy test trong sandbox] ──fail──┐
      ↓ pass                        │
[Đo coverage]                       │
      ↓ chưa đủ                      │
[Xác định nhánh còn thiếu] ─────────┘  (vòng lại sinh thêm)
      ↓ đủ
[Kết xuất test file + báo cáo]

Bốn thành phần bắt buộc: bộ đọc context, LLM sinh code, runner chạy test trong môi trường cô lập, và bộ đánh giá (pass/fail + coverage).

Ví dụ cụ thể

Giả sử bạn có hàm:

def apply_discount(price, code):
    if price <= 0:
        raise ValueError("price must be positive")
    if code == "VIP":
        return price * 0.8
    return price

Một prompt một lần có thể quên test nhánh price <= 0. Agent sẽ chạy coverage, thấy dòng raise ValueError chưa được chạm, và tự sinh thêm test cho case đó. Đây chính là điểm khiến agent vượt trội: nó không dừng ở test trông có vẻ đúng, mà dừng khi số liệu đạt.

Các bước để bắt đầu tư duy như một agent builder

  • Xác định tín hiệu thành công đo được (measurable signal): coverage %, số test pass, mutation score — không phải "trông ổn".
  • Đảm bảo có môi trường chạy test tự động (pytest, jest…) mà agent có thể gọi và đọc output.
  • Thiết kế vòng lặp dừng đúng lúc: đạt mục tiêu thì dừng, quá N vòng thì báo cáo và dừng an toàn.
  • Luôn giữ con người ở vòng review cuối: agent sinh, người duyệt trước khi merge.

Khung tư duy: "Generate → Execute → Evaluate → Refine" (GEER)

Mỗi khi thiết kế agent test, hỏi 4 câu:

  • Generate: agent lấy context gì để sinh?
  • Execute: chạy ở đâu, cô lập thế nào?
  • Evaluate: đo bằng số liệu nào?
  • Refine: khi chưa đạt, vòng lại thông tin gì?
Nếu thiếu bất kỳ chữ nào, bạn đang có script chứ chưa có agent.

Khi nào nên dùng agent, khi nào không

Agent sinh test tỏa sáng ở code có logic nhánh rõ ràng, hàm thuần, module utility, service tầng nghiệp vụ — nơi đầu vào/đầu ra dễ xác định. Ngược lại, với code phụ thuộc nặng vào UI, timing thực, hoặc hành vi khó xác định (non-deterministic), agent dễ sinh test giòn (brittle) hoặc flaky. Hiểu ranh giới này giúp bạn triển khai đúng chỗ, thu ROI thật thay vì tạo gánh nặng bảo trì mới. Một chiến lược thực dụng: bắt đầu ở lớp logic thuần nhất, chứng minh giá trị, rồi mới mở rộng dần ra vùng khó hơn khi guardrails đã vững.

Sai lầm thường gặp

  • Coi output LLM là test luôn dùng được: không chạy thử, dẫn tới test sai import hoặc assertion vô nghĩa.
  • Không đo coverage: agent "tưởng" đã xong nhưng bỏ sót nhánh, đây là cái bẫy lớn nhất.
  • Vòng lặp không có điều kiện dừng: agent lặp vô hạn hoặc đốt token khi gặp lỗi không thể sửa.
  • Bỏ review con người: merge thẳng test agent sinh, để lọt test khẳng định hành vi sai (test that locks in a bug).
  • Áp agent vào chỗ sai: ép sinh test cho code UI/timing khó xác định rồi than phiền agent kém, trong khi vấn đề là chọn sai điểm áp dụng.
Bài tiếp theo ta sẽ thiết lập môi trường và công cụ để agent thực sự chạy được test, chứ không chỉ sinh chữ.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi