Vì sao một nhà cung cấp thư là hình dạng sai cho QA
Mọi cách cấp địa chỉ email cho một bộ kiểm thử đều đã được thử qua, và mỗi cách lại rò rỉ ở một chỗ khác nhau:
| Cách tiếp cận | Cái giá phải trả | Nó gãy ở đâu |
|---|---|---|
Một hộp thư dùng chung (qa@company.com) | Không cần thiết lập gì cả. | Bài kiểm thử nào cũng đọc nhầm thư của bài kiểm thử khác. Lượt thăm dò đầu tiên của một lượt chạy mới tìm thấy mã của lượt chạy trước. Chạy song song là bất khả thi. |
Cộng-thẻ (plus-addressing) (qa+run42@company.com) | Không cần thiết lập gì cả, nếu nhà cung cấp hỗ trợ kiểu này. | Đó vẫn chỉ là một hộp thư duy nhất: một quota, một lượt đăng nhập IMAP dùng chung cho cả team, và một biểu mẫu đăng ký sẽ bỏ thẻ đi hoặc từ chối luôn dấu +. |
| Một hộp thư cho mỗi tester từ nhà cung cấp | Mỗi người một suất tài khoản, và một ticket để tạo ra nó. | Không ai cấp phát một hộp thư cho từng lượt chạy kiểm thử cả. Các tester dùng lại hộp thư của chính mình, và vấn đề hộp thư dùng chung quay trở lại, chỉ là từng người một. |
| Một tên miền catch-all trỏ về đây | Một bản ghi DNS, một lần duy nhất. | Hộp thư này công khai với bất kỳ ai biết địa chỉ, và thư tồn tại trong 5 ngày. Cả hai điều đó đều ổn với một mã chỉ quan trọng trong mười một giây; nhưng không điều nào ổn với thư khách hàng thật. |
Hàng thứ tư chính là nội dung của hướng dẫn này. Đó là cùng một cơ chế mà các tên miền dùng một lần công khai vận hành trên đó — một máy chủ chấp nhận mọi địa chỉ trên một tên miền thay vì một danh sách hộp thư — được áp dụng cho một cái tên mà không ai ngoài bạn đang dùng.
Bản ghi DNS duy nhất
Tại nhà cung cấp DNS của bạn, hãy thêm một bản ghi MX duy nhất tại gốc của một tên miền bạn sở hữu. Không cần bản ghi nào khác, không cần TXT để chứng minh gì cả, không cần tài khoản trên trang này:
Bản ghi MX cho tên miền10 smtp.grabmail.io
- Công bố bản ghi MX. Priority 10, trỏ đến
smtp.grabmail.io. Hãy xóa mọi bản ghi MX khác trên tên miền đó — thư chỉ có thể được chuyển đến một nơi duy nhất, và một bản ghi còn sót lại sẽ gửi một phần thư đi nơi khác. - Chờ DNS cập nhật. Thường chỉ mất vài phút; đôi khi lâu bằng TTL của bản ghi cũ từng có ở đó trước đây.
dig MX qa-example.comsẽ cho biết khi nào nó đã có hiệu lực. - Gửi một thư đến bất kỳ địa chỉ nào trên đó. Lượt chuyển thư đầu tiên chính là thứ kết nối tên miền: máy chủ tra cứu MX ngay tại khoảnh khắc đó, thấy chính mình trong đó, và chấp nhận. Từ đó trở đi, mọi địa chỉ trên tên miền đều là một hộp thư.
Một hình mẫu đặt tên tự nói lên ai đã tạo ra hộp thư
Vì mọi địa chỉ đều hợp lệ, local part hoàn toàn tự do để mang thông tin — và vào lúc hai giờ sáng, với một lượt chạy thất bại và một hộp thư đang mở, bạn sẽ muốn nó làm đúng điều đó. Ba phần, nối với nhau bằng dấu gạch ngang, theo thứ tự sau:
| Phần | Ví dụ | Nó mang lại lợi ích gì |
|---|---|---|
| Cái gì đã tạo ra nó | signup, reset, e2e, alice | Chỉ cần liếc qua là biết hộp thư đó thuộc về luồng nào hoặc người nào. |
| Lượt chạy nào | 1234567890 (id lượt chạy CI), một tên nhánh, một ngày tháng | Mọi hộp thư từ cùng một lượt chạy pipeline đều mang chung một token mà bạn có thể tìm kiếm. |
| Tính ngẫu nhiên | 3f9a1c2e | Tám ký tự ngẫu nhiên. Đây chính là phần khiến hai bài kiểm thử, hai shard, hay hai lượt thử lại không bao giờ dùng chung một hộp thư. |
| Không bao giờ: bất cứ thứ gì có thật | tên một khách hàng, một user id thật, một mã ticket nêu tên khách hàng | Hộp thư này công khai với bất kỳ ai biết địa chỉ. Không có gì trong địa chỉ nên đáng để biết đến cả. |
// one helper, every runner: who made it, which run, and eight random characters
export const testAddress = (who: string, run = process.env.GITHUB_RUN_ID ?? 'local') =>
`${who}-${run}-${crypto.randomUUID().slice(0, 8)}@qa-example.com`;
testAddress('signup'); // signup-1234567890-3f9a1c2e@qa-example.comĐọc bất kỳ địa chỉ nào, cùng ba lệnh gọi
Không có gì trong API thay đổi khi dùng tên miền riêng của bạn. Cùng lệnh gọi liệt kê, cùng lệnh gọi lấy thư, cùng lệnh xóa — không cần key ở gói công khai, và tên miền trong địa chỉ là thứ duy nhất khác đi:
$ curl -sG https://grabmail.io/api/v1/mailbox --data-urlencode "address=signup-1234567890-3f9a1c2e@qa-example.com"Điều đó có nghĩa là mọi helper trên trang này đều hoạt động nguyên vẹn sau khi chỉ cần sửa một hằng số: fixture của Playwright, task của Cypress, các module Python và Node. Có ba điều đáng biết mà các tên miền công khai không bao giờ khiến bạn phải bận tâm:
- Một lỗi
404nghĩa là MX chưa có ở đó - Lượt liệt kê trả về
404cho một tên miền không được lưu trữ ở đây. Với tên miền riêng của bạn, đó là vấn đề DNS — bản ghi chưa kịp lan truyền, hoặc trỏ đi nơi khác — chứ không phải vấn đề của API. Hãy chạydig MXtrước tiên. - Alias cũng hoạt động trên tên miền của bạn
- Mọi hộp thư, trên bất kỳ tên miền nào, đều có một địa chỉ thứ hai trên một tên miền riêng biệt, chuyển thư vào hộp thư đó nhưng không đọc được nó. Hãy đưa địa chỉ đó cho một trang web khi bạn muốn nó không thể mở được hộp thư; còn bạn thì thăm dò trên địa chỉ thật của chính mình.
- Một địa chỉ bận rộn sẽ được phân trang
- Một địa chỉ catch-all hứng thư dội ngược hay cả một ngày thông báo có thể chứa nhiều hơn một trang 200 thư. Hãy truyền
nextngược lại thànhbeforecho đến khi nó lànull.
Giữ cho một tên miền kiểm thử luôn dùng được
Một tên miền riêng của bạn không nằm trong bất kỳ danh sách chặn email dùng một lần nào, và đó thường chính là lý do để dùng nó ngay từ đầu: ứng dụng đang được kiểm thử từ chối grabmail.io và mọi tên miền công khai khác, đúng như nó nên làm. Bốn thói quen sau giữ cho tình trạng đó tiếp tục:
- Dùng một tên miền riêng biệt —
qa-example.com, không phải một subdomain của production và không phải tên miền khách hàng vẫn viết thư đến. Dịch vụ này chỉ chấp nhận tên miền cấp đăng ký (example.com, không bao giờ làmail.example.com), và một tên miền kiểm thử không nên có nhiệm vụ nào khác. - Đừng công bố nó. Các danh sách chặn được xây dựng từ những gì xuất hiện trên các trang email tạm thời công khai và trong các bộ dữ liệu địa chỉ bị rò rỉ dùng chung. Một tên miền chỉ xuất hiện trong bộ kiểm thử của riêng bạn thì không có cách nào lọt vào đó được.
- Khóa nó lại bằng SPF và DMARC. Một tên miền chỉ nhận thư mà không có SPF là một tên miền mà bất kỳ ai cũng có thể giả mạo để gửi thư đi; hai bản ghi sẽ khóa chặt lỗ hổng đó, và không tốn kém gì cả.
- Đừng trỏ thư thật vào đó. Ngay khoảnh khắc một hệ thống staging gửi thông báo cho khách hàng đến một địa chỉ catch-all, một hộp thư công khai sẽ chứa dữ liệu khách hàng. Tên miền kiểm thử chỉ nên mang thư kiểm thử.
Nếu ứng dụng từ chối mọi tên miền catch-all — một số bước kiểm tra gian lận làm vậy, bằng cách dò xem một địa chỉ ngẫu nhiên trên tên miền đó có được chấp nhận hay không — thì có một nhóm tên miền .com trả phí, trông như bình thường, được giữ ngoài các danh sách chặn, mô tả trên trang bảng giá. Bài vì sao biểu mẫu đăng ký chặn email dùng một lần giải thích từng kiểu kiểm tra nhìn thấy gì.
Dành cho một team: một tên miền, nhiều tester, nhiều pipeline
Một tên miền catch-all duy nhất phục vụ cho tất cả mọi người, vì local part là thứ duy nhất cần khác nhau, và việc đó thì miễn phí. Điều một team cần là sự thống nhất về cách đặt tên ở trên, cùng ba quy ước nhỏ:
- Một tiền tố cho mỗi pipeline và mỗi người
e2e-,nightly-,alice-. Tìm kiếm tiền tố đó trong log của một job sẽ ra mọi hộp thư mà job đó đã tạo; tìm tiền tố của một đồng nghiệp sẽ ra đúng lỗi mà họ đang xem xét.- Không bao giờ dùng chung bất cứ thứ gì
- Không có “hộp thư chung của team” nào trên tên miền đó, và không có fixture nào phát ra một địa chỉ cố định. Nếu hai người cần cùng một hộp thư, một trong hai người sẽ gửi địa chỉ đó cho người kia.
- Các giới hạn tốc độ được tính theo từng client
- Một lần đọc mỗi giây cho mỗi địa chỉ, 1200 yêu cầu mỗi phút cho mỗi client — một CI runner là một client, một laptop là một client khác. Một team mười người cùng chạy bộ kiểm thử một lúc là mười client, chứ không phải một.
Các giới hạn được áp dụng
Tên miền riêng của bạn nhận được cùng một dịch vụ như các tên miền công khai, với cùng những mức trần. Không mức nào có thể điều chỉnh, và không mức nào là vấn đề đối với một bộ kiểm thử:
| Giới hạn | Giá trị | Ý nghĩa đối với QA |
|---|---|---|
| Thời gian lưu | 5 ngày cho mỗi thư | Mỗi lượt chạy tự tạo ra thư của riêng nó; không gì từng được lấy lại từ một tuần trước đó. Các quy tắc chính xác. |
| Tệp đính kèm | 5 MB cho mỗi thư | Đủ cho một PDF hóa đơn hoặc một tệp xuất CSV; một thư lớn hơn sẽ bị từ chối ngay tại thời điểm SMTP, nên bên gửi sẽ được báo ngay. |
| Lượt đọc | 1 lần mỗi giây cho mỗi địa chỉ, 1200 lần mỗi phút cho mỗi client | Hai mươi hộp thư được thăm dò mỗi giây một lần từ một runner. Vượt quá đó, 429 kèm Retry-After. |
| Quyền riêng tư | Không có — bất kỳ ai biết một địa chỉ đều đọc được nó | Local part ngẫu nhiên, một tên miền không công bố, và không có thư khách hàng thật. |
| Gửi thư | Không có | Tên miền này chỉ nhận thư. Ứng dụng của bạn gửi thư qua nhà cung cấp riêng của nó, giống như trong production. |
Trước khi bạn coi như đã xong
- Một tên miền cấp đăng ký riêng biệt, với một bản ghi MX:
10 smtp.grabmail.io, và không có bản ghi MX nào khác. - Một thư đã được gửi đến bất kỳ địa chỉ nào trên đó, và đọc lại được qua API.
- SPF và DMARC đã được công bố, để không ai có thể gửi thư mạo danh tên miền đó.
- Một helper đặt tên — ai, lượt chạy nào, tám ký tự ngẫu nhiên — được mọi bộ kiểm thử sử dụng.
- Tên miền được giữ trong cấu hình môi trường, không bao giờ trong code, ảnh chụp màn hình, hay ticket.
- Không có gì gửi thư khách hàng thật được trỏ vào đó.
Từ đây trở đi, các bộ kiểm thử đều đã được viết sẵn: Playwright với tên miền nằm trong fixture của nó, kỷ luật không phụ thuộc runner cụ thể, và workflow GitHub Actions với tên miền nằm trong một biến.
Câu hỏi
Tôi có thể dùng một subdomain, kiểu như test.company.com không?
Không — dịch vụ này chỉ chấp nhận tên miền cấp đăng ký (company.com, hoặc company.co.uk), vì ai kiểm soát một tên miền thì kiểm soát mọi cái tên bên dưới nó, và hai bên không được phép cùng nắm giữ hai nửa chồng lấn của một namespace. Hãy đăng ký một tên miền riêng biệt, giá rẻ, dành riêng cho việc kiểm thử; dù sao đó cũng là cách làm tốt hơn.
Bao lâu thì bản ghi MX bắt đầu hoạt động?
Ngay khi DNS phục vụ bản ghi đó, thường chỉ trong vài phút. Nếu trước đó đã có một MX khác, TTL của nó sẽ được áp dụng. Tên miền được kết nối bởi thư đầu tiên đến sau đó — không cần gì khác phải xảy ra cả, và dig MX sẽ cho bạn biết khi nào bản ghi đã có hiệu lực.
Việc này có tốn phí gì không?
Không tốn gì cả. Việc kết nối một tên miền, mọi địa chỉ trên đó, và API đều miễn phí, không cần tài khoản. Thứ trả phí duy nhất trên trang này là một nhóm tên miền được giữ ngoài các danh sách chặn email dùng một lần, dành cho những ai không thể dùng tên miền riêng của mình.
Người khác có thể đọc được thư trên tên miền của tôi không?
Bất kỳ ai biết một địa chỉ đều đọc được, y hệt như trên các tên miền công khai. Điều tên miền riêng của bạn thay đổi là khả năng bị đoán ra: các địa chỉ trên đó mang một cái tên không ai khác đang dùng. Local part ngẫu nhiên và một tên miền không công bố khiến việc đoán mò trở nên bất khả thi; nhưng chúng không khiến hộp thư trở nên riêng tư, và không gì ở đây làm được điều đó cả.
Điều gì xảy ra với thư gửi đến tên miền trước khi tôi kết nối nó?
Không gì đến được đây cho tới khi MX trỏ về đây. Thư gửi trong lúc bản ghi cũ còn hiệu lực đã đi đến máy chủ cũ, hoặc bị trả ngược; thư gửi sau khi DNS chuyển đổi sẽ đến nơi và kết nối tên miền.
Làm sao để ngắt kết nối tên miền?
Xóa bản ghi MX. Thư mới sẽ ngừng đến ngay lập tức; bất cứ thứ gì đã có sẵn trong các hộp thư sẽ tự hết hạn trong vòng 5 ngày. Không có gì về tên miền đó được giữ lại sau đó.
Ứng dụng cũng từ chối luôn tên miền kiểm thử của tôi. Giờ phải làm sao?
Một số bước kiểm tra gian lận từ chối bất kỳ tên miền nào chấp nhận một địa chỉ ngẫu nhiên — một phép thử catch-all — thay vì đối chiếu với một danh sách. Với những trường hợp đó, cần một tên miền hoạt động giống một nhà cung cấp hộp thư thông thường, và đó chính là thứ nhóm tên miền trả phí cung cấp; bài vì sao biểu mẫu đăng ký chặn email dùng một lần giải thích bạn đang gặp phải kiểu kiểm tra nào.


