Cách kiểm thử SMS OTP trong CI: Mock, sandbox và SMS thật

Cách kiểm thử SMS OTP trong CI: Mock, sandbox và SMS thật

Kiểm thử SMS OTP thường hỏng ở một chỗ khá khó chịu: ứng dụng đã tạo mã, nhưng bộ kiểm thử lại không có cách đọc tin nhắn như người dùng. Nếu mọi bài kiểm tra đều gửi mã về số cá nhân, CI sẽ chậm, tốn phí và dễ để lại dữ liệu nhạy cảm trong log. Nếu mọi thứ đều bị giả lập, đội ngũ có thể bỏ sót lỗi ở nhà cung cấp SMS, mạng di động hoặc thiết bị.

Bài toán không phải là chọn một công cụ duy nhất. Hãy chọn đúng điểm kiểm tra cho từng lớp của hệ thống: mã kiểm thử cố định hoặc gateway giả cho phần lớn bài chạy tự động, thông tin xác thực sandbox để kiểm tra đường gửi, rồi một số bài smoke dùng số nhận SMS do đội ngũ kiểm soát để kiểm tra luồng thật.

Minh họa quy trình kiểm thử SMS OTP với gateway giả và bài smoke trên thiết bị thật

Bốn cách đưa SMS vào bài kiểm thử

Trước khi viết test, hãy xác định bạn muốn kiểm tra phần nào. Kiểm tra logic xác thực không cần nhà mạng thật. Kiểm tra toàn bộ đường đi của tin nhắn thì cần một hộp thư SMS có thể truy cập bằng API hoặc một thiết bị được quản lý.

Cách làmPhù hợp vớiĐiểm cần đánh đổi
Mã cố định trong môi trường testUnit, integration, CIKhông kiểm tra việc gửi SMS thật
Gateway SMS giảKiểm tra request và nội dungKhông phản ánh hành vi nhà mạng
Thông tin xác thực sandboxKiểm tra hợp đồng API và lỗi gửiThường không có tin nhắn để đọc
Số nhận SMS do đội ngũ kiểm soátSmoke và end-to-end trước phát hànhChậm hơn, có chi phí và biến động bên ngoài

Trong thực tế, một bộ test cân bằng thường dùng gateway giả hoặc mã test cho các lần chạy thường ngày. Bài end-to-end với số nhận SMS chạy theo lịch hoặc trước khi phát hành. Cách này giúp CI không phụ thuộc vào thời gian giao tin nhắn, nhưng vẫn có người kiểm tra khoảng cách giữa môi trường test và mạng di động thực tế.

Mã test cố định và gateway giả

Nếu bạn sở hữu môi trường staging, có thể cấu hình ứng dụng chấp nhận một mã chỉ trong môi trường đó, chẳng hạn 000000. Mã này phải bị vô hiệu hóa ngoài test, được bảo vệ bằng cấu hình rõ ràng và có test để chứng minh production không bật chế độ test. Cách này rất nhanh khi kiểm tra thời hạn mã, số lần nhập sai, resend, lockout và trạng thái phiên.

Gateway giả đi thêm một bước. Thay vì bỏ qua lớp gửi, ứng dụng vẫn gọi một endpoint có cùng hợp đồng với nhà cung cấp, còn máy chủ giả chỉ lưu request trong bộ nhớ hoặc fixture. Test có thể kiểm tra số nhận, nội dung, biến động trong template và mã được tạo. Bạn cũng có thể mô phỏng lỗi timeout, phản hồi 4xx, giới hạn tốc độ hoặc trạng thái provider không khả dụng mà không gửi tin nhắn thật.

Điểm chặn nên nằm ở ranh giới HTTP của nhà cung cấp, không phải ở toàn bộ chức năng đăng ký hay đặt lại mật khẩu. Khi đó, phần tạo mã, lưu mã, kiểm tra thời hạn và cập nhật trạng thái vẫn chạy như trong ứng dụng thật. Hãy dọn dữ liệu sau mỗi lượt và không ghi mã OTP đầy đủ vào output của CI.

Kiểm tra đường gửi bằng sandbox

Một số nền tảng nhắn tin có chế độ sandbox hoặc thông tin xác thực kiểm thử. Chúng hữu ích khi bạn cần biết ứng dụng gửi đúng tham số, xử lý phản hồi và phản ứng đúng với lỗi số điện thoại hoặc template. Tuy nhiên, phản hồi thành công trong sandbox không chứng minh tin nhắn đã đi qua nhà mạng, đến thiết bị hay hiển thị đúng trên màn hình.

Hãy tách rõ hai assertion. Assertion thứ nhất kiểm tra request gửi đi: người nhận, sender, nội dung, template và metadata. Assertion thứ hai, ở bài end-to-end, kiểm tra tin nhắn đến hộp thư hoặc thiết bị. Đừng dùng một phản hồi API mô phỏng để kết luận về độ trễ hay khả năng giao SMS ngoài đời.

Chạy smoke test với số nhận SMS

Để kiểm tra đầy đủ, dùng một số nhận SMS thuộc quyền kiểm soát của nhóm hoặc được ủy quyền rõ ràng. Ghi lại mốc thời gian ngay trước khi bấm “Gửi mã”, sau đó truy vấn hộp thư qua API và chỉ lấy tin nhắn mới hơn mốc đó. Nếu chỉ lấy tin nhắn mới nhất mà không có mốc thời gian, một mã cũ từ lượt chạy trước có thể làm test pass giả.

Trình lấy mã nên có thời hạn chờ, khoảng nghỉ giữa các lần truy vấn và mẫu khớp phù hợp với định dạng mã của ứng dụng. Nếu nội dung có nhiều dãy số, đừng lấy sáu chữ số đầu tiên một cách mù quáng; hãy neo biểu thức vào phần văn bản quanh mã hoặc kiểm tra thêm sender, người nhận và ID của lượt chạy.

Không nên chạy bài SMS thật trên mọi commit. Nhà cung cấp, carrier và thiết bị nằm ngoài quyền kiểm soát của codebase, nên một lần timeout chưa chắc là lỗi ứng dụng. Hãy lưu riêng các nguyên nhân như ứng dụng không gọi provider, provider từ chối, tin nhắn đến muộn hoặc test đọc nhầm hộp thư. Dùng số riêng cho các lượt chạy song song để chúng không lấy mã của nhau.

Với những nhóm cần một số nhận SMS tạm thời cho QA được ủy quyền, BinOTP có thể là một ví dụ để đưa lớp nhận tin nhắn thật vào bài smoke. Hãy chỉ dùng số và dịch vụ mà bạn có quyền kiểm thử, đồng thời kiểm tra trước quy định của nền tảng và chính sách lưu giữ dữ liệu.

💡 Giải pháp gợi ý: BinOTP

  • Hỗ trợ 180+ quốc gia, 400+ dịch vụ
  • Nhận OTP trong vòng 5 giây
  • Chỉ tính phí khi nhận được mã — giá từ 500đ
  • API cho lập trình viên tích hợp dễ dàng

👉 Dùng thử miễn phí tại binotp.com

Checklist cho OTP và SMS

Một bài happy path chỉ xác nhận mã đúng giúp người dùng đi tiếp. Bộ regression nên kiểm tra thêm mã sai, mã hết hạn, nhập sai quá số lần cho phép, resend, replay mã đã dùng, gửi trùng và yêu cầu gửi liên tục. Với mỗi trường hợp, ghi rõ trạng thái mong đợi, thông báo hiển thị và việc hệ thống có tiết lộ số điện thoại tồn tại hay không.

  • Kiểm tra định dạng số theo E.164 và các ký tự bản địa hóa trong nội dung.
  • Kiểm tra mã mới có vô hiệu hóa mã cũ theo đúng đặc tả hay không.
  • Kiểm tra timeout, retry và xử lý phản hồi lỗi của provider.
  • Kiểm tra log đã che số điện thoại, mã OTP và token hay chưa.
  • Kiểm tra test credential, endpoint test và cờ sandbox không thể dùng trong production.
  • Kiểm tra các lượt chạy song song không chia sẻ nhầm inbox hoặc fixture.

Giữ test an toàn và dễ chẩn đoán

Dùng tài khoản, số điện thoại và dịch vụ do nhóm sở hữu hoặc có ủy quyền. Không dùng số công khai cho tài khoản quan trọng, vì tin nhắn trong inbox chung không phải bí mật. Lưu credential trong kho bí mật của CI, giới hạn quyền truy cập và xoay khóa khi cần. Nhật ký chỉ nên giữ mã đã che, ID lượt chạy, thời gian và trạng thái đủ để điều tra.

Khi test thất bại, trả lời ba câu hỏi: ứng dụng có phát sinh yêu cầu không, provider có chấp nhận yêu cầu không, và tin nhắn có đến hộp thư hoặc thiết bị không? Phân tách ba lớp này giúp tránh sửa sai chỗ. Một gateway giả cho biết logic của ứng dụng có ổn không; một bài smoke có lịch chạy cho biết kết nối với thế giới bên ngoài còn hoạt động không.

Cách chia lịch chạy

Unit và integration test với gateway giả nên chạy trên mỗi pull request. Smoke test với sandbox có thể chạy khi thay đổi tích hợp hoặc cấu hình. End-to-end với số nhận SMS nên chạy theo lịch và trước các đợt phát hành quan trọng. Sau một sự cố thực tế, bổ sung một bài test cho đúng failure mode đó thay vì chỉ tăng số lượng test.

Đừng biến việc kiểm thử SMS thành cuộc đua săn một con số tỷ lệ thành công. Mục tiêu là biết lớp nào đã được kiểm tra, lớp nào còn phụ thuộc bên ngoài, và khi có lỗi thì đội ngũ có thể tái hiện bằng dữ liệu sạch hay không. Khi cần kiểm tra SMS thật trong một quy trình QA được phép, BinOTP là một lựa chọn để tham khảo tại binotp.com; còn phần lớn regression vẫn nên giữ nhanh, cô lập và không gửi tin nhắn cho người dùng thật.

Thuê SIM nhận OTP từ 500đ
Dùng thử