Hãy tưởng tượng một ticket hỗ trợ với tiêu đề vỏn vẹn bốn từ: đã trả tiền, không có gì xảy ra, cứu. Nó rơi xuống lúc 8 giờ 52 sáng thứ Hai — thời điểm tệ nhất có thể để bắt đầu tìm hiểu về luồng thanh toán của chính mình. Nếu bạn đã làm sản phẩm trả phí một thời gian, một phiên bản nào đó của câu chuyện này chắc chắn nghe quen tai.
Khách hàng chẳng làm gì bất thường. Đăng ký tối Chủ nhật, bị phân tâm trước khi kịp mở email xác minh, sáng hôm sau quay lại, đi thẳng tới trang bảng giá và thanh toán. Giao dịch thành công. Rồi sau đó không có gì cả — không hóa đơn, không nâng gói, không lời chào mừng. Dưới góc nhìn của sản phẩm, đây là một lượt đăng ký dang dở nhưng tình cờ đã trả tiền.
Mọi test đều xanh. Đăng ký đã được kiểm thử. Việc gửi email đã được kiểm thử. Luồng thanh toán được kiểm thử rất kỹ, bởi những người thật sự quan tâm. Lỗi trú ngụ đúng ở nơi duy nhất không ai sở hữu: tác vụ tạo hóa đơn đọc một trường chỉ được điền khi ai đó bấm vào liên kết xác minh, còn vị khách này lại trả tiền trước khi bấm. Một trình tự sự kiện hoàn toàn bình thường với anh ta, nhưng chưa từng có test nào trong bộ kiểm thử đi qua, bởi mọi test đều bắt đầu từ một người dùng đã xác minh sẵn.
Các mối nối luôn như vậy. Đội đăng ký sở hữu phần đăng ký. Đội thanh toán sở hữu phần hóa đơn. Khoảng trống ở giữa thuộc về bất kỳ ai tình cờ đi ngang — và nếu không ai chủ động bước qua đó, người đầu tiên đi qua sẽ là một khách hàng đang trả tiền vào sáng thứ Hai.
Lý do bạn không bao giờ tìm ra: bạn không thể là người mới
Đây là phần khó chịu. Ngay cả khi đã biết về một lỗi như thế, tái hiện nó vẫn rất vướng víu — vì bạn không dễ gì trở thành người dùng mới. Địa chỉ email của bạn đã nằm sẵn trong bảng người dùng. Nó cũng là một bản ghi khách hàng bên cổng thanh toán, một liên hệ trong công cụ marketing, một dòng trong analytics, và là thành viên của hai nhóm feature flag mà bạn đã quên bẵng. Trình duyệt của bạn thì đang mang theo một phiên đăng nhập, một thẻ đã lưu và một tooltip onboarding bạn tắt từ quý trước.
Khi kiểm thử đăng ký bằng chính địa chỉ của mình, bạn đang đi trên con đường mà không khách hàng thật nào từng đi. Bạn nhảy cóc qua đúng đoạn mà họ mắc kẹt, và không bao giờ nhìn thấy trạng thái trống, lời chào mời nâng gói lần đầu, hay email chào mừng đã lặng lẽ ngừng gửi từ tháng Ba.
Để thật sự là người mới cần hai thứ cùng lúc: một danh tính hệ thống chưa từng thấy, và một trình duyệt chưa từng gặp hệ thống. Mỗi thứ chỉ mất khoảng một phút chuẩn bị. Bỏ qua một trong hai, lượt chạy đó chẳng nói cho bạn điều gì.
Dựng sân khấu
Một hộp thư email tạm thời lo trọn nửa phần danh tính — một địa chỉ không tồn tại ở bất kỳ đâu trong hệ thống của bạn, sẵn sàng trong một giây, và vẫn đọc được khi hóa đơn xuất hiện hai mươi phút sau. Phần còn lại chỉ là kỷ luật với trạng thái:
- Một hồ sơ trình duyệt sạch, chứ không chỉ là cửa sổ ẩn danh. Chế độ ẩn danh xử lý cookie, nhưng một hồ sơ riêng còn có nghĩa là không tiện ích mở rộng và không thẻ tự điền — cả hai đều âm thầm thay đổi hành vi của trang thanh toán.
- Một địa chỉ mà sản phẩm này chưa từng thấy, để bạn tạo ra bản ghi mới thay vì va vào bản ghi cũ.
- Một danh tính thanh toán mới nữa. Dùng lại khách hàng thử nghiệm nghĩa là dùng lại thẻ đã lưu và lịch sử hóa đơn của họ, tức đúng cái trạng thái mà người mua lần đầu không hề có.
- Một cái tên và một công ty khác. Dữ liệu trông giống dữ liệu test sẽ kích hoạt các quy tắc kiểm tra khác với dữ liệu trông giống của người thật.
- Môi trường staging, trỏ tới cổng thanh toán ở chế độ test. Không bao giờ dùng production, không bao giờ dùng thẻ thật.
Bước 1: Đăng ký, và thật sự đọc email
Dán địa chỉ vào rồi gửi. Thư nên tới trong vài giây — nếu mất ba mươi giây, hãy ghi lại, vì một người dùng nhìn chằm chằm màn hình "hãy kiểm tra hộp thư" suốt nửa phút là người dùng đang bắt đầu nghi ngờ bạn. Sau đó hãy đọc tử tế thay vì chỉ săn cái nút:
- Thời gian thư tới. Hãy đo. Đây là chỉ số xuống cấp khi tải cao, và không ai nhận ra cho tới ngày ra mắt.
- Người gửi là ai. Một tên thương hiệu dễ đọc, hay một hostname no-reply? Trả lời thư có tới được người thật không, hay bay vào hư vô?
- Liên kết, bấm hai lần. Lần một để xác minh. Lần hai để xác nhận token chỉ dùng được một lần và lần thử thứ hai bị từ chối một cách lịch sự thay vì ném ra lỗi 500.
- Hết hạn. Để một liên kết không dùng cho quá thời hạn sống của nó, rồi kiểm tra xem nó có bị từ chối kèm thông báo hướng dẫn cách lấy liên kết mới hay không.
- Chữ hoa chữ thường. Đăng ký lại với cách viết hoa khác. Phần tên miền không phân biệt hoa thường theo RFC 5321, và gần như mọi sản phẩm cũng xử lý phần local giống vậy, nên điều này không được phép tạo ra tài khoản thứ hai.
- Trạng thái chưa xác minh — chính là tình huống ở đầu bài. Trước khi bấm bất cứ thứ gì, hãy xem ứng dụng đã cho phép bạn làm những gì. Bạn mời được đồng đội không? Bạn thanh toán được không? Đôi khi đó là chủ ý. Đôi khi đó là một ticket sáng thứ Hai đang chờ xảy ra.
Nếu xác minh là mối bận tâm chính của bạn, nó xứng đáng có một phiên riêng — chúng tôi đã đi sâu hơn vào token và các trường hợp biên trong bài cách các lập trình viên kiểm thử luồng xác minh email.
Bước 2: Quãng lặng trước khi tiền dịch chuyển
Giữa xác minh và thanh toán là một cụm nhỏ các thư tự động — chào mừng, nhắc onboarding, "hoàn tất thiết lập tài khoản của bạn". Đây là những email ít được kiểm thử nhất ở hầu hết sản phẩm, vì chúng do các tác vụ nền gửi chứ không phải một nút bấm mà ai đó nhấn trong lúc test.
Cứ để hộp thư mở và quan sát. Một email chào mừng bị trùng, một lời nhắc bắn ra chín mươi giây sau khi đăng ký, hay một lời chào gọi bằng cái tên bạn chưa hề nhập — tất cả đều là lỗi thật, và tất cả đều vô hình trừ khi có người thật ngồi đọc hộp thư.
Bước 3: Bước thanh toán — luôn luôn trong sandbox
Giờ đến phần ai cũng rón rén né tránh, vì đụng vào thanh toán có cảm giác nguy hiểm. Nó chỉ nguy hiểm khi ở sai môi trường. Mọi nhà cung cấp nghiêm túc đều có sandbox đúng cho việc này: Stripe công bố một bộ thẻ thử đầy đủ, còn PayPal cung cấp tài khoản sandbox hoạt động y như thật mà không dịch chuyển một xu nào.
Hãy dùng chúng. Đừng bao giờ gõ số thẻ thật vào môi trường kiểm thử — không phải thẻ của bạn, và càng không phải thẻ của đồng nghiệp hay khách hàng. Dữ liệu thẻ thật kéo luôn cả cỗ máy bạn đang ngồi vào phạm vi PCI DSS, mà máy staging là nơi cuối cùng thứ đó nên xuất hiện. Số thẻ thử tồn tại để chuyện này không bao giờ phải trở thành một quyết định cảm tính.
Giá trị nằm ở chỗ từ chối dừng lại ở kịch bản suôn sẻ. Một luồng thanh toán chỉ chạy được khi mọi thứ đều thuận lợi thì chưa thật sự được kiểm thử:
- Một lần thành công sạch sẽ. Thanh toán được duyệt, gói thật sự kích hoạt, người dùng đáp xuống một nơi có ý nghĩa chứ không phải bảng điều khiển trống trơn.
- Một lần từ chối thông thường. Người dùng nhận được lời giải thích rõ ràng và giữ nguyên dữ liệu đã nhập, hay nhận một stack trace cùng giỏ hàng rỗng?
- Không đủ số dư. Khác với từ chối chung chung, và xứng đáng có câu chữ riêng.
- Một thử thách 3-D Secure. Xác thực khách hàng mạnh là bắt buộc ở nhiều thị trường. Hoàn tất một lần — rồi chạy lại và bỏ dở giữa chừng. Một thử thách bị bỏ dở không được để lại phía sau một gói đăng ký xây dựng nửa vời.
- Thẻ hết hạn và sai CVC. Hai nhánh lỗi rất hay bị gộp lại thành một thông báo vô dụng duy nhất.
- Gửi hai lần. Bấm thanh toán hai lần thật nhanh. Một lần trừ tiền, không phải hai. Nếu lọt ra ngoài, đây là lỗi đắt giá nhất trong danh sách này.
- Nút quay lại. Thanh toán, quay lại, gửi lại. Cùng một câu hỏi, đi bằng cửa khác.
- Tiền tệ và thuế. Nếu bạn tính phí khác nhau theo khu vực, hãy chạy hai khu vực. Thuế được tính ở một chỗ và hiển thị ở ba chỗ, rồi ba chỗ đó lệch nhau.
Nếu bạn dùng Stripe, các số thẻ dưới đây phủ trọn danh sách trên và giúp bạn khỏi phải lục tài liệu giữa chừng. Kết hợp bất kỳ số nào với một ngày hết hạn trong tương lai và một mã CVC ba chữ số bất kỳ:
4242 4242 4242 4242— thành công sạch sẽ. Mốc chuẩn của bạn.4000 0000 0000 0002— từ chối chung chung.4000 0000 0000 9995— không đủ số dư, và với người dùng thì thông báo phải khác với từ chối chung chung.4000 0000 0000 0069— thẻ hết hạn.4000 0000 0000 0127— sai CVC.4000 0025 0000 3155— buộc kích hoạt thử thách xác thực 3-D Secure. Chạy hai lần: một lần hoàn tất, một lần bỏ dở giữa chừng.
Các nhà cung cấp khác cũng công bố bộ tương đương, nên sáu kịch bản này vẫn dùng được — chỉ đổi số thẻ. Thỉnh thoảng nên đối chiếu lại với tài liệu kiểm thử hiện hành, vì các nhà cung cấp có sửa đổi danh sách này.
Bước 4: Hóa đơn cũng là một phần của sản phẩm
Ngay khoảnh khắc thanh toán thành công, hộp thư trở thành màn hình thú vị nhất trong cả buổi kiểm thử. Hóa đơn thường được làm sau cùng và bị quên đầu tiên, nhưng với khách hàng đó chính là bằng chứng cho thấy mọi thứ đã thật sự diễn ra — tệp họ chuyển tiếp cho kế toán, tệp đính kèm trong đề nghị hoàn ứng.
- Số tiền khớp với trang thanh toán. Nghe hiển nhiên, nhưng sai nhiều hơn bạn muốn một khi có giảm giá, tính theo tỷ lệ và quy đổi tiền tệ chen vào.
- Thuế được tách đúng cho khu vực bạn đã kiểm thử.
- Tên gói là tên hướng tới khách hàng, không phải
plan_pro_v2_2024. - Số hóa đơn, ngày tháng và thông tin công ty có mặt đầy đủ và người thật đọc hiểu được.
- Tệp PDF hoặc liên kết hóa đơn mở được với người chưa đăng nhập. Bạn kế toán nhận thư chuyển tiếp không hề có tài khoản.
- Mọi liên kết đều trỏ tới nơi công khai. Môi trường staging rất hào hứng nhét URL localhost vào email.
Bước 5: Gia hạn và thanh toán thất bại, không cần chờ cả tháng
Lỗi liên quan tới gói đăng ký ẩn mình trong tương lai, và đó là lý do chúng sống dai đến vậy. Lần trừ tiền gia hạn, cảnh báo thẻ sắp hết hạn, chuỗi nhắc nợ, thông báo hủy cuối cùng — tất cả đều xảy ra hàng tuần sau khi phát hành, và lúc đó chẳng còn ai canh hộp thư nữa.
Bạn không cần phải chờ. Test clock của Stripe tua nhanh một khách hàng thử nghiệm qua nhiều chu kỳ thanh toán chỉ trong vài giây, và phần lớn nhà cung cấp đều có thứ tương đương. Chĩa nó vào một hộp thư dùng một lần, và cả năm thư từ liên quan tới hóa đơn sẽ đổ về trong ít phút:
- Hóa đơn gia hạn được gửi đúng ngày với đúng số tiền.
- Thông báo sắp bị trừ tiền, nếu bạn có gửi, đến sớm đủ để còn hữu ích.
- Chuỗi nhắc nợ tăng dần hợp lý khi thẻ liên tục thất bại — và dừng ngay khoảnh khắc thanh toán thành công. Người đã trả tiền rồi thì không nên nhận lời nhắc gay gắt lần thứ ba.
- Thông báo hạ gói và khóa quyền khớp với những gì tài khoản thật sự còn làm được.
Bước 6: Hủy, rồi hoàn tiền
Hãy đi tới tận cùng. Hủy đăng ký và kiểm tra xem thư xác nhận có nói đúng sự thật về việc quyền truy cập kéo dài tới hết kỳ đã trả hay dừng ngay lập tức — chỉ một câu đó thôi tạo ra nhiều ticket phản hồi giận dữ hơn bất kỳ câu nào khác trong mảng thanh toán. Sau đó hoàn tiền từ phía nhà cung cấp và xác nhận rằng giấy báo có hoặc xác nhận hoàn tiền thật sự đến tay khách hàng, thay vì tiền lặng lẽ dịch chuyển bên trong một bảng điều khiển mà họ không nhìn thấy.
Vòng kiểm tra áp dụng cho mọi thư
Bất kể thứ gì tạo ra nó, mỗi email đều nhận cùng một lượt soi nhanh. Chỉ vài giây, một khi đã thành thói quen:
- Thư đã tới, và tới hộp thư đến chứ không bị âm thầm loại bỏ.
- Không có gì hiển thị dưới dạng placeholder thô. Một token chưa được thay thế trong lời chào là lỗi đáng xấu hổ nhất trong bài này, mà nó vẫn lên production liên tục.
- Phiên bản văn bản thuần tồn tại và đọc trôi chảy. Rất nhiều trình đọc thư và trình đọc màn hình dùng nó thay cho HTML.
- Liên kết là tuyệt đối và truy cập công khai được.
- Thư marketing có nút hủy đăng ký hoạt động, bao gồm header hủy bằng một cú nhấp theo RFC 8058, hiện gần như bắt buộc với người gửi số lượng lớn theo hướng dẫn dành cho người gửi của Google. Hóa đơn giao dịch thì không nên có.
- Xác thực đạt. Nếu thư kiểm thử bị phân phối kém, hãy tìm ra ngay bây giờ — vì sao email giao dịch rơi vào thư rác phân tích các nguyên nhân.
Vì sao hộp thư dùng một lần hợp với vòng lặp này
Điều khiến cách làm này khả thi là hộp thư vừa dùng một lần vừa không ngắn ngủi đến mức vô dụng. Thư về theo thời gian thực, nên bạn thấy từng lá thư đáp xuống đúng khoảnh khắc hệ thống gửi đi, và mối quan hệ nhân quả luôn rõ ràng. Địa chỉ sống được một tiếng, thừa sức bao trọn một lượt đăng ký, một lượt thanh toán, một vòng vèo qua 3-D Secure và một chu kỳ hóa đơn được tua nhanh — trong khi hộp thư mười phút thường hết hạn đúng lúc hóa đơn sắp tới.
Và sau đó chẳng có gì phải dọn dẹp. Không có tài khoản thử nghiệm chất đống trên địa chỉ thật của bạn, không có hộp thư QA dùng chung nơi lượt chạy của sáu người trộn lẫn vào nhau, không phải phân vân xem lá thư trên màn hình thuộc lượt chạy hôm nay hay thứ Năm tuần trước. Lần thử tiếp theo bắt đầu từ con số không thật sự, và đó chính là điểm mấu chốt. Nếu muốn biết chi tiết chuyện gì xảy ra với tất cả sau khi hết một tiếng, chúng tôi đã viết trong bài điều gì xảy ra sau một giờ.
Cách làm này thật sự bắt được những gì
Một lượt chạy như vậy luôn lôi ra được một họ lỗi rất đặc trưng — những lỗi sống ở giữa các hệ thống chứ không phải bên trong chúng:
- Hóa đơn không bao giờ được gửi vì một tác vụ phía sau cần một trường mà một bước hoàn toàn không liên quan mới điền vào. (Chào buổi sáng, thứ Hai.)
- Trừ tiền hai lần chỉ vì một cú nhấp thứ hai thiếu kiên nhẫn.
- Email chào mừng gửi hai lần, hoặc không hề gửi, cho những người thanh toán trước khi xác minh.
- Thanh toán thành công nhưng gói lặng lẽ không kích hoạt, để khách hàng đã trả tiền mắc kẹt ở bậc miễn phí.
- Thử thách 3-D Secure bị bỏ dở để lại những gói đăng ký nửa vời không ai nhận.
- URL staging nằm trong email, chỉ cách khách hàng đúng một cờ cấu hình.
- Chuỗi nhắc nợ vẫn đuổi theo người đã thanh toán từ lâu.
Một lưu ý, nói thẳng
Đây là kỹ thuật để kiểm thử phần mềm mà bạn chịu trách nhiệm, trong môi trường bạn kiểm soát, đối chiếu với một sandbox thanh toán. Nó không phải cách để gom bản dùng thử miễn phí, né tường phí hay chế tạo tài khoản trên dịch vụ của người khác. Đó là lạm dụng, đó là lý do các nhà cung cấp email dùng một lần bị chặn, và đó không phải mục đích của công cụ này.
Giới hạn cũng đúng theo chiều ngược lại: hộp thư dùng một lần vốn cố tình mang tính tạm thời, nên đừng bao giờ gắn nó với tài khoản bạn cần giữ lâu dài. Nếu không có hộp thư đó mà bạn không khôi phục được tài khoản, hãy dùng địa chỉ thật. Alias so với địa chỉ tạm thời là bài nên đọc nếu bạn chưa chắc mình đang đứng ở phía nào của ranh giới đó.
Biến nó thành thói quen, đừng biến thành chiến công
Những đội bắt được các lỗi kiểu này không phải là đội có kế hoạch kiểm thử cầu kỳ nhất. Đó là những đội đi trọn con đường với tư cách người lạ trước khi bất cứ thứ gì quan trọng được phát hành — hộp thư mới, hồ sơ sạch, đăng ký, xác minh, thanh toán bằng thẻ thử, đọc từng lá thư, hủy, hoàn tiền. Nửa tiếng, hoàn toàn thủ công, mà vẫn liên tục tìm ra những thứ bộ kiểm thử tự động về mặt cấu trúc không thể tìm ra, bởi bộ kiểm thử ấy được dựng trên đúng những giả định giống như mã nguồn.
Hãy đưa nó vào lịch — hai tuần một lần, hoặc trước mỗi bản phát hành có động tới đăng ký hay thanh toán. Lượt chạy đầu tiên gần như luôn moi ra thứ gì đó chưa ai để ý, và chiếc ticket sáng thứ Hai thôi không còn là chuyện xảy đến với bạn nữa. Lấy ngay một email dùng một lần mới rồi đi hết con đường đó.