なぜメールプロバイダはQAに向いていないのか
テストスイートにメールアドレスを与える方法はひととおり試されてきましたが、そのどれもが、違う場所でほころびます。
| 方式 | コスト | 破綻する場所 |
|---|---|---|
1つの共有受信箱(qa@company.com) | セットアップ不要。 | すべてのテストが、他のすべてのテストのメールを読んでしまいます。新しい実行の最初のポーリングが、前回の実行のコードを見つけてしまいます。並列実行は不可能です。 |
プラスアドレッシング(qa+run42@company.com) | プロバイダが対応していれば、セットアップ不要。 | それでも1つのメールボックスであることに変わりはありません。1つのクォータ、チーム全体で共有する1つのIMAPログイン、そしてタグを取り除くか+を拒否するサインアップフォーム。 |
| プロバイダからテスターごとに1つのメールボックス | 1人ずつの席と、それを作成するためのチケット。 | テストの実行ごとにメールボックスをプロビジョニングする人はいません。テスターは自分のものを使い回し、共有受信箱の問題が1人単位で戻ってきます。 |
| ここに向けたキャッチオールドメイン | DNSレコード1件、一度だけ。 | メールボックスは、アドレスを知っている人なら誰でも見られる公開状態にあり、メールは5日間残ります。どちらも、11秒しか意味を持たないコードには問題ありませんが、本物の顧客宛てメールにはどちらも向いていません。 |
4行目が、このガイドの内容です。これは、公開の使い捨てドメインを動かしているのと同じ仕組み — メールボックスの一覧ではなく、ドメイン上のあらゆるアドレスを受け入れるサーバー — を、自分以外誰も使っていない名前に適用したものです。
唯一のDNSレコード
自分のDNSプロバイダで、所有しているドメインのアペックスにMXレコードを1件追加してください。それ以外のレコードは不要で、何かを証明するTXTレコードも、このサイトのアカウントも必要ありません。
ドメイン用のMXレコード10 smtp.grabmail.io
- MXを公開する。優先度10で、
smtp.grabmail.ioを指すように。そのドメイン上の他のMXレコードは削除してください — メールは1か所にしか配信できず、残っているレコードがあると、一部が別の場所へ送られてしまいます。 - DNSの反映を待つ。通常は数分です。まれに、以前あったレコードのTTL分かかることもあります。反映されたかどうかは
dig MX qa-example.comで確認できます。 - そのドメイン上のどれかのアドレスへ、メッセージを1通送る。最初の配信こそが、ドメインを接続するものです。サーバーはその瞬間にMXを調べ、自分自身を見つけ、受理します。それ以降、そのドメイン上のすべてのアドレスがメールボックスになります。
誰がメールボックスを作ったかを示す命名規則
すべてのアドレスが有効である以上、ローカルパートは自由に情報を運べます — そして朝の2時、実行が失敗してメールボックスを開いているときには、そうであってほしいと思うはずです。ハイフンでつないだ、次の順序の3つの部分です。
| 部分 | 例 | 得られるもの |
|---|---|---|
| 何が作ったか | signup、reset、e2e、alice | 一目で、そのメールボックスがどのフローの、あるいは誰のものかがわかります。 |
| どの実行か | 1234567890(CIの実行ID)、ブランチ名、日付 | 1回のパイプライン実行から生まれたメールボックスはすべて、検索可能な共通のトークンを持ちます。 |
| ランダム性 | 3f9a1c2e | 8文字分です。この部分があるおかげで、2つのテスト、2つのシャード、2回のリトライが、決して同じメールボックスを共有しません。 |
| 絶対に入れないもの — 本物の情報 | 顧客名、実際のユーザーID、顧客名を含むチケット番号 | メールボックスは、アドレスを知っている人なら誰でも見られる状態にあります。アドレスの中に、知る価値のあるものを入れてはいけません。 |
// 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どのアドレスも、同じ3つの呼び出しで読み取る
独自ドメインであっても、APIについて変わることは何もありません。同じ一覧取得の呼び出し、同じメッセージ取得の呼び出し、同じ削除 — 無料プランではキーも不要で、違うのはアドレスの中のドメイン部分だけです。
$ curl -sG https://grabmail.io/api/v1/mailbox --data-urlencode "address=signup-1234567890-3f9a1c2e@qa-example.com"つまり、このサイトのすべてのヘルパーは、定数を1つ編集するだけで変更なしに動作します。Playwrightのフィクスチャ、Cypressのタスク、PythonとNodeのモジュールも同様です。公開ドメインでは考えずに済んでいた、知っておく価値のある点が3つあります。
404は、MXがまだ設定されていないという意味- 一覧取得は、ここでホストされていないドメインに対して
404を返します。独自ドメインの場合、それはAPIの問題ではなくDNSの問題です — レコードがまだ反映されていないか、別の場所を指しています。まずdig MXを確認してください。 - エイリアスは、自分のドメインでも機能する
- どのドメイン上のどのメールボックスにも、別のドメイン上の第2のアドレスがあり、そこへ配信はしますが、そこから読み取ることはできません。受信箱を開けさせたくないサイトにはそちらを渡し、自分自身のアドレスをポーリングしてください。
- 混雑したアドレスはページングされる
- バウンスメールや1日分の通知を集めるキャッチオールアドレスは、200件の1ページを超えて保持することがあります。
nextをbeforeとして渡し続け、nullになるまで繰り返してください。
テストドメインを使い続けられる状態に保つ
独自ドメインは、使い捨てメールのどのブロックリストにも載っていません。そもそもこれこそが、独自ドメインを使う理由であることが多いはずです。テスト対象のアプリケーションがgrabmail.ioや他の公開ドメインをすべて拒否するのは、まさに想定どおりの動作です。その状態を保つための習慣が4つあります。
- 専用のドメインを使う —
qa-example.comのようなもので、本番のサブドメインでも、顧客が書き込むドメインでもありません。このサービスが受け付けるのは登録可能なドメインだけです(example.comであって、mail.example.comではありません)。テストドメインには、それ以外の役目を持たせないでください。 - 公開しない。ブロックリストは、公開の使い捨てメールサイトや共有のアドレスダンプに現れるものから作られます。自分のテストスイートの中にしか出てこないドメインは、そこに載りようがありません。
- SPFとDMARCで固める。SPFのない受信専用ドメインは、誰でもそこからのメールを詐称できるドメインです。2つのレコードでそれを塞げますし、コストもかかりません。
- 本物のメールを向けない。ステージング環境が顧客向けの通知をキャッチオールアドレスに送信した瞬間、公開されたメールボックスが顧客データを保持することになります。テストドメインには、テスト用のメールだけを流してください。
アプリケーションがあらゆるキャッチオールドメインを拒否する場合 — 一部の不正検知は、そのドメイン上のランダムなアドレスが受理されるかどうかを調べることでこれを行います — ブロックリストに載っていない、ごく普通に見える.comドメインの有料プールが用意されています。詳しくは料金ページにあります。サインアップフォームが使い捨てメールをブロックする理由では、それぞれの種類のチェックが何を見ているかを解説しています。
チームの場合 — 1つのドメイン、複数のテスター、複数のパイプライン
1つのキャッチオールドメインが全員をカバーします。異なる必要があるのはローカルパートだけで、それは自由に決められるからです。チームに必要なのは、上記の命名規則についての合意と、3つの小さな取り決めだけです。
- パイプラインごと、人ごとの接頭辞
e2e-、nightly-、alice-のように。ジョブログをその接頭辞で検索すれば、そこから作られたすべてのメールボックスが見つかり、同僚の接頭辞で検索すれば、その人が調べているバグが見つかります。- 何も共有しない
- そのドメイン上に「チーム用の受信箱」は存在せず、固定のアドレスを配るフィクスチャもありません。2人が同じメールボックスを必要とする場合は、一方がもう一方にアドレスを送ってください。
- レート制限は、クライアントごと
- アドレスあたり1秒に1回の読み取り、クライアントあたり1分に1200リクエスト — CIランナーは1つのクライアントであり、ノートパソコンはまた別のクライアントです。10人のチームが同時にスイートを実行すれば、それは1つではなく10のクライアントになります。
適用される上限
独自ドメインも、公開ドメインとまったく同じサービス、同じ上限を受けます。どれも調整はできませんが、どれもテストスイートにとって問題にはなりません。
| 上限 | 値 | QAにとっての意味 |
|---|---|---|
| 保存期間 | メッセージあたり5日間 | すべての実行が自分自身のメールを作るため、前の週のものを取得することは決してありません。正確なルールはこちら。 |
| 添付ファイル | メッセージあたり5 MB | 請求書のPDFやCSVのエクスポートには十分な大きさです。それを超えるメッセージはSMTPの時点で拒否されるため、送信者にはそれが伝わります。 |
| 読み取り | アドレスあたり1秒に1回、クライアントあたり1分に1200回 | 1つのランナーから、1秒に1回のポーリングで20個のメールボックス分です。それを超えると、Retry-After付きの429が返ります。 |
| プライバシー | なし — アドレスを知っている人なら誰でも読めます | ランダムなローカルパート、非公開のドメイン、そして本物の顧客宛てメールを流さないこと。 |
| 送信 | なし | このドメインは受信専用です。アプリケーションは、本番環境と同じく、自身のプロバイダを通じて送信します。 |
完了とみなす前に
- 専用の、登録可能なドメインに、MXレコード1件を設定する。
10 smtp.grabmail.io。他のMXは置かない。 - そのドメイン上のどれかのアドレスへメッセージを1通送り、APIで読み取れることを確認する。
- SPFとDMARCを公開し、誰もそのドメインとして送信できないようにする。
- 誰が、どの実行か、8文字のランダム文字列 — この命名ヘルパーを、すべてのスイートで使う。
- ドメインは環境設定の中に保ち、コードやスクリーンショット、チケットには決して書かない。
- 本物の顧客宛てメールを送るものを、これに向けない。
ここから先のスイートは、すでに書かれているものと同じです。フィクスチャにドメインを設定したPlaywright、テストランナーを問わない作法、そして変数にドメインを設定したGitHub Actionsのワークフローです。
質問
test.company.comのようなサブドメインを使えますか?
いいえ — このサービスが受け付けるのは登録可能なドメインだけです(company.comやcompany.co.ukなど)。ドメインを管理している者は、その配下のすべての名前を管理することになり、2つの当事者が1つの名前空間を分け合ってしまうことがあってはならないからです。テスト用に安価な専用ドメインを登録してください。そのほうが、いずれにせよ良い実践です。
MXレコードが機能するまで、どれくらいかかりますか?
DNSがそれを配信し始めた瞬間からで、通常は数分です。以前MXレコードがあった場合は、そのTTLが適用されます。ドメインは、その後最初に届いたメッセージによって接続されます — それ以外に何かをする必要はなく、レコードが有効になったかどうかはdig MXでわかります。
費用はかかりますか?
いいえ。ドメインの接続、そのドメイン上のすべてのアドレス、そしてAPIは、アカウント不要で無料です。このサイトで唯一の有料のものは、独自ドメインを使えない人向けの、使い捨てメールのブロックリストに載らないドメインのプールです。
自分のドメインのメールを、他の誰かが読めてしまいますか?
公開ドメインとまったく同じように、アドレスを知っている人なら誰でも読めます。独自ドメインが変えるのは、推測されやすさです。そのアドレスは、他の誰も使っていない名前の上にあります。ランダムなローカルパートと非公開のドメインによって、推測は現実的でなくなりますが、それでメールボックスが非公開になるわけではありません。それは、ここのどの仕組みにも当てはまりません。
ドメインを接続する前に送られたメールは、どうなりますか?
MXがここを指すまで、何もここには届きません。古いレコードが有効だった間に送られたメールは、古いサーバーに届いたか、バウンスしています。DNSが切り替わった後に送られたメールは、ここに届き、ドメインを接続します。
ドメインの接続を解除するには、どうすればいいですか?
MXレコードを削除してください。新しいメールはすぐに届かなくなります。すでにメールボックスに入っているものは、5日以内に自然に期限切れになります。それ以降、そのドメインについて保持されるものは何もありません。
アプリケーションが、自分のテストドメインまで拒否してしまいます。どうすればいいですか?
一部の不正検知は、リストと照合するのではなく、ランダムなアドレスを受理するドメインをすべて拒否します — いわゆるキャッチオールの探査です。その場合は、普通のメールボックスプロバイダのように振る舞うドメインが必要で、それこそが有料プールの提供するものです。サインアップフォームが使い捨てメールをブロックする理由で、自分がどちらの種類のチェックに直面しているかを確認できます。


