Tempcase

Tempcase テストノート

OTP再送テスト:
メールを各リクエストに紐付ける

再送を2回クリックしたのに、先に届いたのは2通目だった。まず、「最後に届いたメール」が「最後に発行されたコード」とは限らないことを押さえましょう。リクエスト、送信イベント、受信記録を紐付ければ、どの段階で問題が起きたのか判断できます。

読了目安:約12分 OTP回帰テスト

OTPテスト用メールアドレスがあれば、メールを受信したことを確認し、本文をチェックできます。ただし、どのコードを有効とするかは業務システムが判断するものであり、受信箱では決められません。ここでは、テスト権限のあるステージング環境と、実資産に紐付かないテストアカウントを使います。例にある番号は説明用で、実際の障害記録ではありません。

2026年の自動回帰テストでも、なぜ2回分が混同されるのか

自動化スクリプトでは、「認証コードをリクエスト → メールを待つ → 最新のメールを取得 → 送信」という流れをよく使います。1回の実行で正常に動いても、連続して再送したときに問題がないとは限りません。1通目がキューに残っている間に2回目のリクエストが完了し、同じアカウントを使う2つのウィンドウがあるのに、スクリプトは最後のクリック時刻しか保存していないこともあります。

この場合、受信箱の最新メールが実は先のリクエストに対するものかもしれません。件名、未読状態、到着順だけでメールを取得すると、配信順の入れ替わりをコードの誤りと誤判定したり、たまたま別のコードで認証が通って不具合を見逃したりするおそれがあります。テスト登録メールでは、まずリクエストとの対応関係を確立しましょう。6桁の数字を拾う正規表現を書くのはその後です。

再送ルールは受信箱から推測せず、先に確認する

OTP再送テストの前に、プロダクトチームとバックエンドチームに確認して、実行可能なルールを決めておきましょう。再送では有効なコードを再利用するのか、新しいコードを発行するのか。新しいコードを発行したら、いつ旧コードを無効にするのか。有効期限は最初の発行時と今回の発行時のどちらを基準にするのか。ルールの適用単位はアカウント、用途、それとも検証セッションなのか。

先に期待値を決めてから、到着順を入れ替える

「最新のコードだけが有効」と「有効期限内なら複数のコードが使える」は別の仕様です。後者では、旧コードが通っただけで不具合と判断すべきではありません。ただし、どちらの仕様でも試行回数、レート制限、有効期限、認証成功後にコードを一度だけ使えるようにするルールを定義する必要があります。

テストケースにはルールのバージョンを記録しましょう。ルールが未確定なら、確認事項として記録し、自動テストのアサーションでチームに代わって仕様を決めないでください。後述の再現例では、「新しいコードの発行成功後、旧コードは直ちに無効になる」というルールを前提とします。

1テストケースにつき1つのアドレス:アドレスはコンテキストの一部

まず使い捨て受信箱から専用アドレスを取得し、このテストにケースIDを割り当てます。たとえば case-r17です。同じテスト内では、初回送信と再送に同じアドレスを使い、ステージング環境のバージョン、アカウントID、検証用途、セッションIDを記録します。再送をクリックするたびにアドレスを変えると、「同じアカウントでの再送」が「新規アカウントへの初回送信」に変わってしまいます。

各リクエストについて、業務リクエストID、レスポンス結果、送信サービスが生成したイベントIDをそれぞれ記録します。業務APIが成功を返しても、タスクがキューに入ったことしか意味しない場合があります。非同期タスクの送信イベントがまだ作成されていない場合は、該当欄に「未紐付け」と記録し、後で追記します。レート制限などでリクエストが拒否された場合、通常は新しいメールを期待しませんが、最終的にはAPIの仕様に従ってください。

Tempcaseのメール記録IDは受信側のIDであり、業務リクエストIDと自動的に一致するわけではありません。受信詳細にメールヘッダーや対応フィールドが表示されない場合は、送信ログ、制御されたテスト用マーカー、またはテスト環境の観測機能を使って補いましょう。時刻が近いというだけで無理に対応付けてはいけません。

5列の対応表を作り、各メールの送信元を追跡する

次の5列は、最小限の対応関係を記録するためのものです。アカウント、環境、ルールのバージョン、タイムラインはテスト記録の冒頭に記載します。1つのリクエストで複数回の配信試行が発生した場合は、行を分けてリトライとの関係を記録し、古いイベントを上書きしないでください。

記録例:R1とR2は同じテストアドレス、同じ検証セッションを使用
テストケース リクエストID 配信イベントID メール記録ID 業務側の検証結果
case-r17 / R1 req-a evt-a mail-a、後着 旧コードA:拒否される想定、実際は受理
case-r17 / R2 req-b evt-b mail-b、先着 新コードB:独立した再現テストで検証

ここでいう「配信イベント」には、キュー投入、送信サービスへの引き渡し、受信側での受理、バウンスなどの段階も記録します。単に「配信済み」とまとめないでください。メール記録IDは追跡の手がかりにはなりますが、業務側の検証APIの結果に代わるものではありません。

連続再送、複数ウィンドウ、キュー遅延で何を確認するか

連続再送:ルールとレート制限を確認する

許可された再送間隔を空けてR1、R2を送り、それぞれの応答を記録します。その後、クールダウン中にクリックした場合も別途テストしてください。拒否されたリクエストで新しいタスクが本当に作成されなかったか、再送後の有効期限が仕様どおりかを確認します。高頻度のリクエストで負荷をかけたり、レート制限を回避したりしないでください。

複数ウィンドウ:状態の適用範囲を確認する

同じテストアカウントを2つのウィンドウで使い、順序を明確にしてリクエストを実行し、それぞれのセッションIDを記録します。無効化ルールがウィンドウ間でも適用されるかを確認してください。一方のウィンドウに古い案内が表示されていても、サーバーが旧コードを受理するとは限りません。反対に、ページが更新されていても、サーバー側で無効化が完了した証拠にはなりません。

キュー遅延:到着順が入れ替わったときの業務結果を確認する

許可されたテスト環境に限り、制御可能なキューや障害注入を使ってR1を遅延させ、R2を先に配信します。注入箇所と遅延の範囲を記録してください。このテストで確認できるのは、配信順が入れ替わってもシステムがOTPルールを守るかどうかです。実際のネットワークにおける配信遅延を示すものではなく、本番キューを変更してはいけません。

メールの到着順はリクエスト順とは限らない

リクエスト順、コードの発行順、タスクの実行順、受信順は異なることがあります。メールの Date ヘッダーも送信側で生成されるため、受信時刻としてそのまま扱えません。OTPの到着順が入れ替わったかを判断するには、最新のメールだけを見るのではなく、追跡可能なイベントの対応関係を優先してください。

自分で管理するテンプレートには、秘密情報を含まないテスト用の相関IDを入れるか、ログ側でリクエストIDとメールの Message-ID の対応を記録できます。OTP自体を紐付けキーにしてはいけません。システムが同じコードを再利用することもあれば、別々のリクエストで同じ数字が発行されることもあります。紐付けを示す証拠がなければ、「どのリクエストに属するか確認できない」と記録してください。

旧コードが無効かどうかは業務側で確認する

次の3点は分けて検証します。メールが受信箱に届いたか。OTPが業務側で受理されたか。認証成功後に正しいセッションや業務状態が作成されたか。メールを受信したからといってコードが有効とは限りませんし、OTP APIが成功を返してもログイン処理が完了したとは限りません。

旧コードを確認するには、R2の発行成功後にR1のコードを送信し、業務エラーの種類とチャレンジの状態を記録します。新コードが使えるか、認証成功後に再利用できないかは、独立した再現テストで確認しましょう。新コードで先に認証を成功させると、チャレンジ全体が消費されて以降の旧コードが失敗し、再送時に旧コードの無効化が機能していない問題を見逃すおそれがあります。

各テスト分岐では同じ初期条件を作り直し、試行回数の上限を超えないようにします。記録するのは「受理/拒否」と安定したエラー分類に限り、完全な認証コードをアサーションのレポート、スクリーンショットのファイル名、CIログに含めないでください。

時刻の証拠:形式を統一し、出所も記録する

タイムゾーン付きのISO 8601形式を使い、集計時はUTCに統一することをおすすめします。その際、元の値と出所も残してください。「業務サービスの発行時刻」「送信サービスの受理時刻」「受信サービスの記録時刻」「ブラウザーでの観測時刻」は別々の項目名にします。表示形式が同じでも、各マシンの時計が同期しているとは限りません。

  • 同じプロセス内の所要時間には単調時計を使い、比較用に実時刻も記録します。
  • サービス間の時刻を比較する前に、時刻同期の状態を確認します。信頼できる誤差範囲がなければ、時刻を単純に引き算して正確な遅延だと断定しないでください。
  • ポーリングでメールを初めて見つけた時刻は、観測時刻にすぎません。数秒おきにページを確認する場合、その間隔が観測のずれになります。
  • メールヘッダーの時刻は補助情報としてのみ使い、発行、キュー投入、業務側での検証時刻の代わりにしないでください。

「ある確認ではメールがなく、次の確認では見つかった」としか分からない場合は、その時間帯を記録します。測定できない部分を正直に残すほうが、根拠のないミリ秒単位の数値を示すより役に立ちます。

再現例:2通目が先に届き、1通目が後から届く

以下は制御されたテスト例であり、Tempcaseや特定の業務システムで実際に発生した障害を示すものではありません。想定するルールは、同じチャレンジでR2の新コードが正常に発行された時点で、R1の旧コードは直ちに無効になることです。

  1. テスト用のチャレンジを作成してR1を送信し、 req-a → evt-aを記録して、テストキューで配信を遅らせます。
  2. 再送が許可されたらR2を送り、新コードが発行されたことを確認して、 req-b → evt-bを記録します。
  3. まず mail-bを確認し、遅延を解除してから mail-aを確認します。相関IDを使って、2通のメールがそれぞれどのリクエストに属するか確認してください。
  4. チャレンジがまだ消費されていない状態で旧コードAを送信します。受理された場合は、検証レスポンスとチャレンジの状態を記録し、このテスト分岐を直ちに終了します。

不具合記録の要約 · 説明用サンプル

タイトル
同じチャレンジで新コードを発行した後も、旧コードで認証できる
期待される結果
R2の発行成功後、R1の旧コードは拒否されること。
実際の結果
旧コードAが受理された。対応関係を示す記録と検証レスポンスは、機密情報を伏せて保存済み。
注意点
到着順の入れ替わりは発生条件であり、キューが根本原因だとは限りません。無効化処理と検証ロジックを別途確認する必要があります。

1通目が遅れて届いただけで旧コードが正しく拒否されたなら、「到着順の入れ替わり」を認証の不具合と記録してはいけません。メールの案内やページの導線を改善する必要があるかもしれませんが、それはセキュリティルールの不備とは別の問題です。

共有するのは機密情報を伏せた証拠であり、完全な認証コードではない

引き継ぎ資料は、同僚があなたの認証情報を使わずに手順を再現できる内容にします。以下のチェックリストを使い、アカウントはIDで記載し、実際のアドレスや相関IDはチームのデータ分類ルールに従って扱ってください。

最小限の再現記録

  • 環境とビルドのバージョン、ルールのバージョン、テストケース、アカウントID。
  • 初期状態、セッションの適用範囲、リクエスト間隔、遅延の注入方法。
  • 5列の対応表、出所を明記したタイムライン、機密情報を伏せたレスポンス分類。
  • 期待値と実際の結果、再現回数、未検証の分岐、既知の不確定要素。

完全な認証コード、ログイントークン、Cookie、認証リンク、一時メールのアクセストークンを共有レポートに含めないでください。スクリーンショットでは本文に含まれる秘密情報を隠し、録画ではアドレスバーと開発者ツールも確認します。短い数字の認証コードを通常のハッシュで保存するのも避けましょう。候補が少なく、総当たりで特定されやすいためです。A、Bのような無関係な識別子を使ってください。

アドレスを変更するタイミング、同じアカウントを使い続けるタイミング

テストが終わったときや、まっさらな登録フローを検証するときは、アドレスを変えると古いメールを切り分けやすくなります。同じアカウントで再送、複数ウィンドウ、レート制限、旧コードの無効化を検証している間は、同じアドレスとコンテキストを維持してください。変えるとテストの前提そのものが変わってしまいます。

Tempcaseの一時アドレスは標準で3時間有効で、延長できます。1つのアドレスの有効期間は最長24時間です。サービス内で延長をリクエストするたびに3時間追加されますが、上限があります。期限切れのメールは復元できないため、受信箱を証拠保管庫として使わないでください。数日間にわたってアカウントの受信先を維持する必要がある場合は、長期転送のログインページからエイリアスを作成できます。エイリアスは受信メールを転送するだけで、業務ログや無期限の証拠保管の代わりにはなりません。

次のテスト:まず対応関係を確認する

最初の実施ですべての例外を検証する必要はありません。まず、対応関係を追跡できる通常送信を1回行い、次に再送を1回追加し、最後に制御された到着順の入れ替わりを試します。メールが送信されたかどうかも分からない場合は、まず認証コードが届かないときのトラブルシューティングに沿って送信と受信の証拠を確認してください。メールが届いたら本文のレイアウトをチェックし、次にメールテンプレートプレビューを確認します。

新しいテストケースごとに、途切れない証拠の連鎖を。

専用アドレスを用意してから、テスト権限のある登録フローを実行します。受信したメールをリクエストに紐付け、コードの有効性は業務側で検証します。