AI của bạn viết những bài kiểm tra không bao giờ thất bại

Bạn yêu cầu AI viết các bài kiểm tra. Nó đưa cho bạn mười hai bài kiểm tra đều màu xanh. CI của bạn vượt qua. Bạn merge code. Ba ngày sau, một lỗi lọt vào production. Bạn xem lại các bài kiểm tra. Chúng đều vượt qua, nhưng thực tế chúng chẳng kiểm tra được gì cả.

Một bài kiểm tra màu xanh không phải là bằng chứng. Nó chỉ là một giả thuyết. AI viết ra những giả thuyết không bao giờ thất bại.

Hãy nhìn vào hàm này:

func Discount(total int) int {
    if total > 100 {
        return total - 10
    }
    return total
}

Một AI có thể viết bài kiểm tra như thế này:

func TestDiscount(t *testing.T) {
    got := Discount(150)
    if got < 0 {
        t.Errorf("result should not be negative")
    }
}

Bài kiểm tra này có màu xanh. Nó chạy code, nên độ bao phủ (coverage) của bạn trông có vẻ tốt. Nhưng bài kiểm tra này chỉ kiểm tra xem kết quả có nhỏ hơn không hay không. Nếu bạn thay đổi phần giảm giá thành một lỗi toán học, bài kiểm tra vẫn sẽ hiện màu xanh. Nó không kiểm tra hành vi (behavior). Nó chỉ kiểm tra xem "đèn có sáng hay không".

Đây là một cái bẫy. Coverage đếm những dòng code mà bạn chạm tới. Nó không đếm những assertion thực sự quan trọng. Một báo cáo coverage 90% có thể che giấu những đoạn code bị lỗi.

AI luôn muốn tìm con đường ngắn nhất để có được "đèn xanh". Nó chọn những assertion lỏng lẻo và những bản mock không kiểm tra được gì cả.

Để khắc phục điều này, hãy áp dụng một quy tắc: hãy kiểm tra xem một bài kiểm tra có biết cách để thất bại hay không.

Hãy cố tình thay đổi code của bạn. Nếu bài kiểm tra vẫn hiện màu xanh, thì bài kiểm tra đó vô dụng. Hãy vứt nó đi.

Một bài kiểm tra thực thụ sẽ trông như thế này:

func TestDiscount(t *testing.T) {
    if got := Discount(150); got != 140 {
        t.Errorf("Discount(150) = %d, want 140", got)
    }
}

Nếu bạn làm hỏng logic, bài kiểm tra này sẽ chuyển sang màu đỏ ngay lập tức. Nó "cắn" được lỗi.

Bạn không thể làm việc này bằng tay cho mọi bài kiểm tra. Thay vào đó, hãy sử dụng mutation testing. Các công cụ như Gremlins trong Go sẽ áp dụng những thay đổi nhỏ vào code của bạn. Chúng kiểm tra xem các bài kiểm tra của bạn có phát hiện ra những thay đổi đó hay không.

Nếu một thay đổi không làm bài kiểm tra thất bại, nghĩa là bộ kiểm thử (test suite) của bạn đang có lỗ hổng.

Tôi áp dụng cách này cho code do AI viết. Tôi không để AI tự tuyên bố rằng nó đã hoàn thành công việc. Tôi thiết lập một chốt kiểm soát (gate). Công cụ sẽ thực hiện đột biến code. Nếu bài kiểm tra vẫn hiện màu xanh, AI phải viết lại nó. AI không quyết định xem một bài kiểm tra có tốt hay không. Chính sự đột biến mới quyết định điều đó.

Không có bài kiểm tra AI nào được đưa vào codebase của tôi mà không chứng minh được rằng nó có thể thất bại. Một bài kiểm tra không thể thất bại còn tệ hơn là không có bài kiểm tra nào. Một bài kiểm tra bị thiếu thì dễ nhận ra. Một bài kiểm tra giả tạo mới là thứ nguy hiểm.

Đừng tin vào những ánh đèn xanh. Một bài kiểm tra chỉ có giá trị khi nó có thể tạo ra màu đỏ.

Source: https://dev.to/ohugonnot/your-ai-writes-tests-that-can-never-fail-3i57

Optional learning community: https://t.me/GyaanSetuAi