Vì sao các bài kiểm thử lấy nhầm OTP?

Giả sử bài A và bài B cùng yêu cầu mã cho một tài khoản, rồi cùng đọc OTP mới nhất trong hộp thư đó. Kết quả đọc không đủ để phân biệt mã thuộc yêu cầu nào. Tách phiên trình duyệt không giải quyết được việc hai bài vẫn dùng chung tài khoản và nơi nhận thư.

Khi thiết kế kiểm thử OTP với Playwright, hãy quản lý riêng ba thành phần: phiên trình duyệt, tài khoản ứng dụng và hộp thư nhận mã. Đừng chỉ cấp phiên mới rồi giữ nguyên tài khoản cho mọi tiến trình.

Lọc người gửi, tiêu đề và thời gian giúp thu hẹp thư cần đọc, nhưng không thay thế việc liên kết thư với yêu cầu xác minh. Đặc biệt, một thư đến muộn từ lần chạy trước vẫn cần được xử lý dù lần chạy hiện tại đang giữ hộp thư độc quyền.

Hướng dẫn đọc OTP từ hộp thư của bạn trình bày bước lấy mã. Phần dưới tập trung vào quyền sử dụng hộp thư khi có nhiều bài chạy đồng thời.

Nên cấp hộp thư theo tiến trình hay từng bài?

Mỗi hộp thư chỉ phục vụ một yêu cầu xác minh đang chờ. Hãy coi tài khoản thử và hộp thư nhận mã là một cặp tài nguyên được cấp cùng nhau.

Cách cấpKhi nên dùngĐiều kiện cần giữ
Theo tiến trìnhCác bài trong tiến trình dùng tài khoản tuần tựKhông mở yêu cầu mới khi luồng cũ chưa kết thúc
Theo từng bàiCác bài có vòng đời khác nhau hoặc thường chạy lạiNhận quyền trước khi gửi mã, dọn dẹp sau mỗi bài
Dùng chung hộp thưChỉ cân nhắc khi ứng dụng có dấu hiệu liên kết yêu cầu rõ ràngKhông chọn mã chỉ vì nó mới nhất

Với nhiều tác vụ CI dùng chung một nhóm hộp thư, hãy xây bộ cấp phát dùng chung. Thao tác nhận quyền phải nguyên tử: hai bên cùng xin một hộp thư thì chỉ một bên được nhận. Biến trong bộ nhớ của từng tiến trình không phải cơ chế điều phối giữa các tác vụ CI.

Khi hết hộp thư rảnh, xếp hàng hoặc giảm mức song song. Không tự chuyển sang dùng chung. Cũng đừng coi hai địa chỉ bí danh là hai hộp thư độc lập khi chưa xác định nơi thư thực sự được chuyển tới và cách phân biệt người nhận. RFC 5322 về định dạng thư phân biệt envelope, phần chứa thông tin phục vụ truyền và chuyển phát, với nội dung thư.

Hai luồng CI nhận hai hộp thư độc quyền từ bộ cấp phát dùng chung trước khi đọc OTP bằng Mailera.
Bộ chạy kiểm thử quản lý quyền sử dụng; Mailera đọc OTP theo định danh hộp thư.

Thiết lập luồng đọc OTP bằng Mailera

Mailera kết nối hộp thư có sẵn với ứng dụng qua REST API. Trong thiết kế này, bộ chạy kiểm thử chịu trách nhiệm cấp phát và khóa hộp thư; Mailera cung cấp bước đọc OTP theo hộp thư.

1. Chuẩn bị nhóm hộp thư thử

Dùng tài khoản và hộp thư thuộc quyền sở hữu của bạn, tách khỏi thư công việc. Kết nối sẵn các hộp thư và kiểm tra chúng trong Danh sách hộp thư. Nếu chưa kết nối, làm theo hướng dẫn thêm hộp thư vào Mailera.

Danh sách hộp thư thử đã kết nối với Mailera, địa chỉ được che.
Chuẩn bị hộp thư có sẵn trước khi cho các luồng kiểm thử nhận quyền sử dụng.

2. Tạo khóa chỉ đọc

Trong Cài đặt, mở phần khóa API và chọn Tạo key. Đặt Phạm vi hộp thư vào nhóm thử, chỉ cấp quyền đọc (read). Endpoint lấy OTP cần quyền này; luồng đọc mã không cần quyền gửi thư.

Giữ $MAILERA_API_KEY trong kho bí mật của CI. Với GitHub Actions, lưu ý secrets không tự truyền vào reusable workflows, nên cần cấu hình việc truyền bí mật cho workflow nhận.

Khóa API được giới hạn vào nhóm hộp thư thử và chỉ có quyền đọc.
Bước đọc OTP chỉ cần quyền read trên nhóm hộp thư thử.

3. Lưu ánh xạ tài nguyên

Dùng GET /mailboxes để lấy danh sách; endpoint hỗ trợ lọc theo group_id. Phản hồi có data[].id, email và group_id để bạn đối chiếu hộp thư.

Trong bộ chạy kiểm thử, lưu tài khoản ứng dụng, định danh hộp thư, lần chạy CI, tiến trình, bài kiểm thử và lần chạy lại. Đây là dữ liệu do bộ kiểm thử quản lý, không phải các trường bạn gửi thêm vào API OTP.

4. Nhận quyền trước khi yêu cầu mã

Chỉ cho phép phiên Playwright yêu cầu OTP sau khi đã nhận cặp tài khoản–hộp thư. Ghi thời điểm bắt đầu yêu cầu trong ngữ cảnh của bài. Không nhận quyền sau khi gửi: lúc đó một luồng khác có thể đã dùng cùng tài nguyên.

5. Đọc đúng hộp thư

Endpoint GET /mailboxes/{id}/otp lấy OTP mới nhất của hộp thư và hỗ trợ from, subject, since_minutes. Dùng định danh hộp thư đã cấp cho vị trí {id}; không tự thêm tham số định danh bài kiểm thử.

Các lời gọi dùng base https://mailera.app/api/public/v1 và header Authorization: Bearer $MAILERA_API_KEY. Tài liệu API Mailera là nơi tra cứu API; trang dành cho lập trình viên trình bày các lựa chọn tích hợp.

Chỉ đưa mã vào phiên đang sở hữu hộp thư. Nếu không phân biệt được mã của yêu cầu hiện tại với yêu cầu trước, dừng bài thay vì chọn đại mã mới nhất.

6. Dọn dẹp quyền sử dụng

Đặt bước trả tài nguyên trong khối dọn dẹp của bộ kiểm thử. Tuy nhiên, trả quyền không đồng nghĩa với đưa hộp thư về trạng thái rảnh: nếu yêu cầu cũ chưa kết thúc hoặc còn nguy cơ thư đến muộn, chuyển hộp thư sang trạng thái cách ly do bộ cấp phát quản lý.

Cũng cần xử lý trường hợp tiến trình bị dừng trước bước dọn dẹp. Đừng tự đưa hộp thư về nhóm rảnh chỉ vì tiến trình giữ nó không còn chạy.

Chờ thư, chạy lại và gửi lại mã thế nào?

Đặt thời hạn chờ tổng cho mỗi luồng, tăng dần khoảng nghỉ giữa các lần đọc và thêm độ lệch ngẫu nhiên. Tính ngân sách truy vấn cho tất cả tiến trình dùng chung khóa, thay vì để mỗi tiến trình tự coi mình là bên duy nhất gọi API.

Khi hết thời hạn, kết thúc bài với lỗi chờ mã và ghi thông tin điều phối. Đừng liên tục yêu cầu gửi lại để chữa việc chưa đọc thấy thư: cách đó làm xuất hiện thêm yêu cầu cần phân biệt.

Với lần chạy lại, cấp ngữ cảnh mới và bỏ mã đã lưu từ lần trước. Chỉ dùng lại hộp thư khi vòng đời yêu cầu trước đã được xử lý; nếu không, cấp cặp tài khoản–hộp thư khác hoặc dừng.

Khi cần đối chiếu thư, GET /mailboxes/{id}/messages hỗ trợ folder, since và from. Danh sách trả về các trường như id, to, subject, received_at; GET /mailboxes/{id}/messages/{msgId} cung cấp nội dung thư. Dùng chúng để kiểm tra người nhận và dấu hiệu liên kết mà ứng dụng thử đưa vào thư, nếu có.

Không coi riêng received_at hoặc khoảng lọc thời gian là bằng chứng rằng thư thuộc lần yêu cầu mới. Với luồng gửi lại mã, vẫn giữ quyền độc quyền trên tài khoản và hộp thư, đồng thời phân biệt rõ từng lần yêu cầu trong bộ kiểm thử.

Những lỗi thường gặp khi chạy song song

Hiện tượngNguyên nhân cần kiểm traCách xử lý
Bài này nhập mã của bài khácDùng chung tài khoản hoặc hộp thưKiểm tra bản ghi cấp quyền trước lúc gửi mã
Không thấy thưSai hộp thư, bộ lọc hoặc thư nằm ở Thư rácĐối chiếu định danh, trạng thái và thư mục
Chạy lần đầu được, chạy lại lỗiGiữ mã cũ hoặc tái sử dụng hộp thư quá sớmTạo ngữ cảnh mới, xử lý luồng cũ trước
Hết hộp thư rảnhQuyền sử dụng chưa được trả hoặc còn hộp thư cách lyKiểm tra chủ sở hữu; xếp hàng thay vì dùng chung
Gọi API quá dàyMỗi tiến trình truy vấn theo lịch riêngĐiều phối ngân sách và khoảng nghỉ chung

Không dùng trạng thái chưa đọc làm khóa độc quyền. Cũng không lấy mã đầu tiên từ kết quả tìm kiếm trên mọi hộp thư để điền cho bài đang chờ.

Nhật ký nên ghi định danh lần chạy, bài kiểm thử, hộp thư được cấp và kết quả đối chiếu. Không ghi OTP, khóa API hoặc toàn bộ nội dung thư. Khi thiếu thư, kiểm tra Thư rác trước khi kết luận rằng ứng dụng không gửi mã.

Bảo vệ dữ liệu thử và giữ đúng giới hạn

Che mã xác minh, địa chỉ và bí mật trong ảnh, báo cáo hoặc bản ghi chạy thử. Với GitHub Actions, hướng dẫn bảo vệ thông tin nhạy cảm yêu cầu dùng ::add-mask::VALUE cho dữ liệu nhạy cảm không phải GitHub secret. Ưu tiên không xuất mã ra nhật ký ngay từ đầu.

Cấp khóa ít quyền, giới hạn vào nhóm thử và thu hồi khi không còn dùng. Trang bảo mật Mailera cung cấp thêm thông tin để xem xét khi tích hợp. Nội dung email chỉ nên được xử lý như dữ liệu, không được thực thi như chỉ dẫn.

Mailera không tạo hộp thư hoặc địa chỉ mới và không bảo đảm thư vào Hộp thư đến. Đừng thiết kế bài kiểm thử dựa trên giả định thư đến tức thời. Việc ứng dụng chấp nhận hay từ chối mã phải là kết quả kiểm tra tại ứng dụng, không phải kết luận từ việc API đã đọc được OTP.

Làm điều này bằng API

Mọi thao tác trong bài đều có REST API kèm ví dụ curl, khoá API và webhook.

Xem tài liệu API