Bạn đã xây dựng nó. Bạn đã bấm thử qua. Nút hoạt động, bản ghi được lưu, bảng điều khiển được cập nhật. Bạn cảm thấy hài lòng.
Nhưng bạn không viết đoạn code đó, và nếu thành thật, bạn có lẽ cũng chưa từng đọc nó. Vậy điều bạn thực sự biết là: nó đã hoạt động một lần, với bạn, khi làm một việc duy nhất bạn đã thử. Mọi thứ còn lại về việc nó có ‘hoạt động’ hay không đều chỉ là niềm tin.
Kịch bản lý tưởng là con đường duy nhất hầu hết mọi người kiểm thử
Đây là những gì việc kiểm thử một ứng dụng vibe coding thường trông như thế nào: bạn tải lên một file và nó được xử lý. Bạn gửi một form và bản ghi xuất hiện. Bạn bấm một nút và luồng công việc chạy. Vậy là xong. Đó là toàn bộ bài kiểm thử.
Đây không phải là lười biếng. Đó là giới hạn tự nhiên của việc kiểm thử thủ công do một người không viết ra logic bên dưới thực hiện. Bạn chỉ có thể nghĩ đến việc kiểm thử những gì bạn có thể tưởng tượng sẽ sai, và nếu không đọc được code, bạn đang kiểm thử bản demo, không phải hệ thống. Kịch bản lý tưởng chắc chắn là con đường duy nhất mà AI đã tối ưu hóa, vì đó chính là kịch bản trong prompt đã tạo ra ứng dụng ngay từ đầu.
Vấn đề là việc sử dụng thực tế không bao giờ chỉ dừng ở kịch bản lý tưởng. Người dùng thật bấm đúp. Họ mở hai tab. Họ bấm quay lại và gửi lại. Không điều nào trong số đó xuất hiện khi bạn, người xây dựng, bấm qua ứng dụng của chính mình một lần, cẩn thận, theo đúng thứ tự bạn kỳ vọng nó được sử dụng.
Tính đồng thời là nơi mọi thứ thực sự đổ vỡ
Ví dụ rõ ràng nhất là tính đồng thời, và việc kiểm thử nó bằng tay thực sự khó, ngay cả khi bạn biết chính xác cần tìm gì.
Hãy tưởng tượng một tính năng dựa trên tín dụng: người dùng khởi chạy một quy trình, việc đó tốn tín dụng, và một lượt kiểm tra số dư sẽ chặn họ khi hết tín dụng. Giờ hãy tưởng tượng cùng người dùng đó mở năm tab và khởi chạy năm quy trình trong cùng một giây, trước khi lượt kiểm tra tính phí đầu tiên hoàn tất. Nếu logic ‘kiểm tra rồi trừ’ không được xây dựng để xử lý sự chồng chéo đó, cả năm quy trình đều có thể vượt qua lượt kiểm tra số dư trước khi bất kỳ quy trình nào ghi nhận một lượt trừ. Kết quả là người dùng chạy các quy trình mà họ không đủ khả năng chi trả, số dư tín dụng trở thành số âm, và trạng thái tài khoản giờ sai theo cách không ai lường trước được.
Bạn sẽ không phát hiện ra điều đó bằng cách bấm một nút một lần. Bạn phải nghĩ đến việc mở năm tab, canh thời điểm các lượt bấm rơi vào cùng một phần giây, và biết rằng ‘kiểm tra số dư’ và ‘trừ số dư’ là hai bước riêng biệt có thể tranh chấp lẫn nhau. Đó không phải là một sơ suất trong kiểm thử. Đó là một loại lỗi mà việc bấm thủ công, từng cái một, về cấu trúc không thể tìm ra được, vì lỗi này chỉ tồn tại khi nhiều thứ xảy ra cùng lúc, và một người kiểm thử đơn độc không dễ gì tạo ra được điều kiện đó một cách có chủ đích, chưa nói đến việc lặp lại nó.
Đây chính xác là loại trường hợp biên mà các nghiên cứu về ứng dụng do AI tạo ra chỉ ra như một dạng lỗi mà không ai lường trước: AI xây dựng các đường dẫn cho đúng kịch bản thành công cụ thể mà nó được yêu cầu, không phải cho các chỉnh sửa đồng thời, các lượt bấm trùng lặp, hay khoảng thời gian lệch giữa các bước. Và vì sự hỏng hóc phát sinh không hiển thị lỗi, nó chỉ nằm im lặng ở đó cho đến khi một báo cáo hoặc số dư trông có vẻ sai vài tuần sau.
Vì sao hầu như không ai viết các bài kiểm thử có thể phát hiện điều này
Giải pháp thực sự cho loại lỗi này là kiểm thử tự động: kiểm thử đơn vị, kiểm thử tích hợp, một thứ gì đó có thể mô phỏng năm yêu cầu đồng thời và kiểm tra kết quả một cách máy móc, thay vì dựa vào sự tưởng tượng và sự kiên nhẫn của con người. Kiểm thử tự động không biết mệt, không quên trường hợp biên, và có thể được chạy lại sau mỗi lần thay đổi để đảm bảo thứ bạn đã sửa vào thứ Hai không bị hỏng vào thứ Ba.
Trong thực tế, những người vibe coding hầu như không bao giờ có điều này. Viết một bộ kiểm thử là một kỹ năng kỹ thuật riêng biệt, có thể nói là còn khó hơn cả việc viết ứng dụng, vì nó đòi hỏi phải suy luận về các kiểu lỗi thay vì chỉ đơn giản là tính năng hoạt động. Một AI agent có thể viết kiểm thử nếu bạn yêu cầu, nhưng vẫn phải có ai đó biết để yêu cầu, hiểu được các bài kiểm thử đó thực sự kiểm tra gì, và duy trì cập nhật chúng khi ứng dụng thay đổi bên dưới. Với một người xây dựng không có kỹ thuật đang triển khai một cổng thông tin cho khách hàng vào chiều thứ Ba, đó là một bước quá xa, và ngay cả những người xây dựng có kỹ thuật vibe coding nhanh cũng hiếm khi dừng lại để viết độ phủ kiểm thử cho đoạn code mà họ sắp thay bằng prompt tiếp theo.
Vậy nên tình trạng thực tế của việc kiểm thử trên hầu hết các ứng dụng vibe coding là: một lượt bấm qua kịch bản lý tưởng, thực hiện một lần, bởi người ít có khả năng đoán được điều gì có thể sai nhất. Đó là khoảng cách niềm tin. Bạn không đang xác minh ứng dụng hoạt động. Bạn đang hy vọng nó hoạt động, dựa trên một điều duy nhất bạn đã thử.
‘Sự chắc chắn trực quan’ thực sự có nghĩa là gì
Có một giải pháp thay thế thực sự cho việc hy vọng, và đó không phải là ‘học cách viết bộ kiểm thử’. Đó là xây dựng những phần rủi ro trên một nền tảng mà logic ngay từ đầu đã không bị ẩn giấu.
Sự chắc chắn trực quan có nghĩa là bạn có thể mở một bảng cài đặt và thấy chính xác nhóm người dùng nào có thể xem một bản ghi, chính xác bộ lọc nào một block áp dụng lên một nguồn dữ liệu, và chính xác một luồng công việc làm gì theo từng bước, theo thứ tự, mà không cần đọc một dòng code nào được sinh ra. Bạn không kiểm thử hành vi rồi suy ra quy tắc đằng sau nó. Bạn đang đọc trực tiếp quy tắc đó.
Điều này quan trọng nhất đối với những hạng mục mà khoảng cách niềm tin có giá đắt nhất: logic tính phí, quyền truy cập, và bất cứ thứ gì liên quan đến người dùng đồng thời. Một nền tảng như Softr giải quyết điều này bằng cách giữ quyền truy cập, hạn chế dữ liệu và các bước luồng công việc dưới dạng cấu hình trực quan, có thể kiểm tra được, thay vì code do AI sinh ra mà bạn phải rà soát từng dòng để tin tưởng. Nếu bạn muốn biết một khách hàng có thể thấy bản ghi của khách hàng khác hay không, bạn mở quy tắc hạn chế dữ liệu ra và đọc nó. Bạn không cần phải mô phỏng năm lượt đăng nhập đồng thời và hy vọng AI xử lý đúng tình trạng tranh chấp, vì chính hạ tầng đã được kiểm thử của nền tảng đang thực thi quy tắc đó, không phải một lượt kiểm tra riêng mà AI viết ra cho prompt cụ thể của bạn.
Điều đó không có nghĩa là mọi tính năng tùy chỉnh đều biến mất vào trong một bảng cài đặt. Đối với giao diện thực sự tùy chỉnh, một block vibe coding được giới hạn trong một component và kết nối qua lớp quyền truy cập và dữ liệu hiện có của nền tảng là một rủi ro rất khác so với toàn bộ logic nghiệp vụ được sinh ra cho cả ứng dụng, vì phạm vi ảnh hưởng của việc ‘AI làm sai một phần này’ chỉ là một block, không phải toàn bộ hệ thống tính phí.
- Mở bảng, đọc quy tắc
- Hiển thị quyền và hạn chế dữ liệu
- Các bước quy trình hiển thị theo thứ tự
- Hạ tầng nền tảng thực thi điều đó
- Thử nghiệm hành vi, suy luận quy tắc ẩn
- Kiểm tra mã từng dòng để tin tưởng
- Mô phỏng năm lần đăng nhập để tìm race conditions
- Kiểm tra tùy chỉnh được viết cho một prompt
Ngã rẽ mà điều này thực sự để lại cho bạn
Nếu ứng dụng của bạn chỉ là một dự án cuối tuần hoặc một bản mẫu mà không ai trả tiền cho nó, hãy phát hành nó, bấm qua kịch bản lý tưởng một lần, và tiếp tục. Rủi ro chính xác là rủi ro của lượt kiểm thử thủ công mà bạn đã thực hiện.
Nếu đó là một cổng thông tin cho khách hàng, một hệ thống đặt lịch, bất cứ thứ gì có tín dụng, số dư, hoặc vai trò, thì câu hỏi trung thực không phải là ‘tôi có kiểm thử điều này chưa?’. Mà là ‘tôi có thể thực sự xác minh những phần sẽ gây tổn hại nếu chúng sai, hay tôi đang tin vào lời của một AI?’. Nếu câu trả lời là niềm tin, đó chính là ngã rẽ tương tự chúng tôi đã từng viết về vấn đề Ngày Thứ Hai, và cả hai nhánh đều hợp lý tùy thuộc vào bạn là ai.
Nếu bạn có thể đọc code, hoặc sẵn sàng học, hãy thu hẹp khoảng cách đó bằng công cụ thực sự thay vì một công cụ xây dựng khác. Cursor hoạt động trong một codebase thực sự, nơi bạn có thể yêu cầu các bài kiểm thử về tính đồng thời và sau đó đọc kết quả trả về, còn Replit cung cấp một môi trường trên cloud, nơi việc chạy một bộ kiểm thử là một phần bình thường của quy trình thay vì một việc nghĩ ra sau cùng. Trong cả hai trường hợp, khoảng cách không nằm ở khả năng của AI, mà ở việc bạn có biết để yêu cầu bài kiểm thử hay không và có thể phân biệt được nó có tốt hay không.
Nếu bạn không thể, và bạn đang xây dựng loại ứng dụng mà một quyền truy cập sai hoặc một số dư âm là một vấn đề thực sự, hãy chuyển những phần rủi ro sang một nền tảng mà bạn đọc được quy tắc thay vì phải đoán nó. Hãy xem bảng xếp hạng cổng thông tin khách hàng của chúng tôi nếu đó là ứng dụng bạn thực sự đang xây dựng, vì đó là nơi một lượt đoán sai tốn kém nhất.