CIで登録確認メールを待ち続けたあと、E2Eテストがタイムアウトする。まず待ち時間を延ばすのではなく、アプリが送信処理を呼んだか、受信側でメールを読めるか、今回の実行に対応するメールか、どのタイムアウトが先に切れたかを分けて確認してください。
この手順は、自社の登録・認証メールを検証する開発者とQAエンジニア向けです。CIの間欠的な失敗や、メールコード・認証リンクを使うフローの切り分けにも使えます。対象は自社製品または許可された環境に限ります。
タイムアウトは「メールが送られていない」という証拠ではありません
テストの断言がタイムアウトしたときに分かるのは、指定された条件が設定時間内に成立しなかったことです。メール未生成、送信処理の応答待ち、受信箱での未確認、検索条件のずれ、テスト設定の上限超過は、どれも似た失敗として見えることがあります。
合格判定には、少なくとも次の証拠を揃えます。
- メールが今回のテスト実行に対応していること。
- 受信側でメールの内容を読み取れること。
- 認証リンクやコードによる操作が完了し、自社製品の想定したアカウント状態になったこと。
「メール送信処理が呼ばれた」「送信側が受け付けた」「テスト用の受信箱で読めた」は別の段階です。SMTPの応答だけでは、最終的な受信箱での確認にはなりません。RFC 5321のSMTP受信責任に関する説明と、自社の送信ログ・受信観察を照らし合わせて判断します。
症状を証拠に置き換える
原因を決めつけず、各段階で確認できる記録を並べます。アプリのログに送信処理が見えない場合と、送信処理は記録されているのに受信箱が空の場合では、調査する場所が異なります。
| 観察できた状態 | まず確認する証拠 | 次に調べる箇所 |
|---|---|---|
| アプリ側に送信処理の記録がない | 登録リクエストと業務条件のログ | 入力検証、登録条件、環境設定、メール処理の呼び出し |
| 送信処理は記録されているが、受信箱で確認できない | 宛先、環境、送信結果、受信側の観察 | 送信経路、キュー、受信先の設定、テスト環境間の食い違い |
| 受信箱にメールはあるが、テストが見つけられない | 検索条件とメールの識別情報 | 読み取り範囲、検索条件、古いメールや別実行との取り違え |
| メールは読めたがテスト全体が失敗する | 断言とテストケースの終了記録 | 認証操作、アカウント状態、各タイムアウトの境界 |
「メールテスト」の手段ごとに確認できる事実は違います。受信箱とテスト用の受信機構の役割を整理する場合は、受信箱とサンドボックスの違いも参考になります。
第一段階:アプリがメール生成処理まで進んだか
まずテストの登録リクエストが自社アプリに届いたかを確認します。リクエストが記録されていなければ、メール受信の調査より先に、テストが使うURL、環境、認証状態、リクエスト内容を見直します。
登録リクエストが届いていても、メール処理が必ず実行されるとは限りません。入力検証やアカウント状態などの業務条件が満たされなかった可能性、メール処理やキューへの登録が呼び出されなかった可能性、テスト側が受信箱の確認を始めていない可能性を、アプリのログとテストの実行記録で分けます。
自社製品の登録フロー自体をどう検証するかは、登録テストの進め方で具体的な確認項目を整理できます。
第二段階:送信側の応答と受信確認を分ける
アプリが「送信済み」と記録していても、その記録だけでテスト用の受信箱にメールがあるとは断定できません。送信処理の戻り値、キューへの登録状況、自社システムが記録する送信結果を確認したうえで、受信側でも実際にメールを読み取れるかを別に調べます。
確認時は、登録に使ったアドレス、送信処理が参照した宛先、テストが見に行く受信箱の三つを照合します。開発環境とCIで異なる設定を参照していると、アプリ側では処理が進んでいても、テスト側は別の受信先を検索していることがあります。メールの送信確認と実着の確認を混同しないための考え方は、Webサイトのメール認証テストにもまとめられています。
第三段階:メールの誤読とタイムアウト設定を切り分ける
受信箱にメールがあるのに失敗する場合は、単純な遅延と決めつけず、検索条件が今回の登録に合っているかを見ます。共有受信箱に古いメールや別の実行のメールが残っていると、検索が空振りしたり、誤ったメールを認証に使ったりします。実行ごとに識別子を持たせ、登録リクエスト、アプリのログ、メール本文や宛先を関連付けてください。
Playwrightの断言は条件を再試行し、expect.pollは指定した処理を繰り返し確認する仕組みです。ポーリングの間隔や上限は設定できますが、固定の待機時間をどの環境にも当てはめるものではありません。Playwrightの断言とexpect.pollの公式説明を確認し、受信処理に合わせて上限を設けます。
また、断言のタイムアウトとテスト全体のタイムアウトは同じ制限ではありません。Playwrightのテストタイムアウトの説明と設定APIを参照し、どの制限が先にテストを終了させたかを確認してください。根拠のない固定待機を追加するより、waitForTimeoutの公式説明を踏まえて、条件を待つ設計にできるか検討します。
修正前に確認する受信テストのチェックリスト
次の項目を埋めると、「待ち時間が足りない」のか、それ以前の段階に原因があるのかを判断しやすくなります。
- [ ] テスト実行ごとの識別子を記録し、登録リクエストと対応付けました。
- [ ] 自社アプリのログで登録リクエストの到達を確認しました。
- [ ] 対象ユーザーでメール生成処理やキュー登録が実行されたか確認しました。
- [ ] 送信処理の応答と、テスト用受信箱での読み取り結果を別々に記録しました。
- [ ] アプリとテストが参照する宛先・環境・受信箱が一致しているか照合しました。
- [ ] メールの検索条件に今回の実行を識別できる情報を含めました。
- [ ] 断言、テストケース、CI実行それぞれの終了理由を確認しました。
- [ ] 認証リンクまたはコードの処理後、アカウント状態が想定どおり変化したか検証しました。
記録には実行識別子、送信処理の記録、受信側での観察、認証後のアカウント状態を残します。受信側で見つからない場合は、その事実を「未着」と断定する前に、宛先や読み取り範囲を確認してください。
FAQ:原因を判断するときの追加ポイント
受信箱が空なら、すぐにメール未着と判定できますか?
できません。テストが参照する宛先がアプリの宛先と違う、検索条件が狭すぎる、確認対象の受信箱が実行環境と合っていない、といった場合にも検索結果は空になります。受信箱の設定と検索対象を照合し、アプリログに記録された送信先と一致した場合に、受信側の観察結果として記録します。
受信できたメールなら、認証テストは成功と見なせますか?
受信だけでは認証フローの完了を証明できません。対象メールが今回の実行に対応していることを確かめ、リンクやコードを使った後に自社製品のアカウント状態が想定どおりになったか確認します。メールの読み取りと認証後の状態確認を別々に判定すると、どの段階が失敗したか追いやすくなります。
CIの失敗をなくすために、タイムアウトを長くすればよいですか?
アプリがメール生成処理を呼んでいない場合や、テストが別の受信箱を見ている場合、待ち時間を延ばしても原因は解消しません。まずテストログとアプリログで終了した段階を特定し、ポーリングの上限や各タイムアウトを調整するのは、処理が正しく動いている証拠がある場合に限ります。成功した一回の実行を、本番の到達保証として扱わないことも重要です。
登録用メールの実着を確かめる必要があるなら、HideRelayの受信方法を自社のテスト手順に加える選択肢もあります。受信先として使う前に、必要なアドレス機能やメールの保存条件を確認し、今回の実行とメールを対応付けてください。短期間の登録検証には受信確認用の方法が役立ちますが、長期保管や重要アカウントの復旧に使うメール先は別に管理するのが適切です。
よくある質問
登録確認メールをE2Eテストで受け取れないとき、最初にどこを確認すればよいですか?
送信APIが成功を返したのに、テスト用の受信箱にメールがありません。なぜですか?
メールテストのタイムアウトは、待ち時間が短いのか、送信処理が動いていないのか、どう見分けますか?
自動テストで、届いたメールが今回の登録に対応するものだと確かめるには?
テスト用通知メールを実際に送信して確認
金額と時刻の期待値を用意したら、テスト用の一時アドレスにメールを送信します。まず実際に届いたことを確認してから、内容を項目ごとに照合してください。サンプルメールを自分のテスト結果として扱わないでください。