メニュー

自動テストのための一時メールボックス API:作成・ポーリング・検証

自動テストで一時メールボックス API を使う手順。HTTP で受信箱を作り、確認メールをポーリングし、コードを取り出して CI で片付ける。

公開日

  • 自動化
  • テスト用メールボックス
  • 継続的インテグレーション

確認メールは、ブラウザを操作するテストだけでは最後まで進めない部分です。誰かがアドレスを持ち、メールを受け取り、コードをテストに戻さなければなりません。一時メールボックス API はまさにその役割を担います。テストスイートは HTTP でサービスに受信箱の作成を依頼し、届いた内容を読み、ケースが終わったら受信箱を捨てます。ブラウザも、人が共有する受信箱も、手作業のコピーも要りません。

本稿が扱うのは、この仕組みの API 側です。アプリケーションをローカルの受信エンドポイントに向ける話ではありません。それはCI でメールを取り込む方法であり、解いている問題が違います。ローカルでの取り込みはアプリが何を送ったかを示し、一時メールボックス API は本物の配送経路を通ってテストが持つアドレスに実際に何が届いたかを示します。

テストでメールボックス API を使う理由は?

もう一方の選択肢が、本物の人の受信箱か、何もないかだからです。

共有の受信箱はテストの土台として貧弱です。複数の実行が同じ受信箱を読み、前の実行のメールがまだ残り、誰も頼んでいないメールがアドレスに溜まっていきます。すると各アサーションは、どのメールが今のケースのものかを推測することになり、その推測こそが不安定さの生まれる場所です。

ブラウザでサービス提供者の画面をかき集めるのは二つ目の悪手です。テストは予告なく変わるマークアップ、セッションの状態、そして見張り続けなければならないログインに依存します。提供者がボタンの見た目を変えた瞬間、製品と無関係な理由で緑のスイートが赤くなります。

メールボックス API はどちらの問題も取り除きます。アドレスはケースのために作られ、構造上必ず空で、テストが直接呼べる安定したインターフェース越しに読めます。スイートは提供者の見た目を気にせず、契約が保たれることだけを気にします。作成、受信、読み取り、削除の四つです。

プライバシーの理由もあります。API で作ったアドレスは誰も表していません。個人の受信箱ではなく、本物のメールが届く場所でもなく、実行と一緒に捨てられます。

テストに本当に必要なエンドポイントは何か?

メールボックス API は何十もの経路を公開できますが、テスト用クライアントに必要なのは四つの操作です。スイートが使う呼び方で名前を付けておくと分かりやすくなります。

作成はアドレスとハンドルを返します。アドレスは、テスト対象のアプリに送信先として伝えるものです。ハンドルは多くの場合トークンや識別子で、以降の呼び出しでその受信箱について尋ねるために使います。スイートは二つを一つの对象として扱い、アドレスからハンドルを組み立て直してはいけません。提供者は両者を無関係にしてよいからです。

一覧は本文ではなく要約を返します。メール一件につき一行で、識別子、差出人、件名、到着時刻が付きます。これはポーリングのループが使うべき呼び出しです。安価で、早い段階で唯一重要な問い、つまり何か届いたかどうかに答えるのに十分だからです。

読み取りは一件のメールを全文で返し、テキスト部分と HTML 部分を含みます。コードがあるのはここで、この呼び出しは一覧が一致を報告してから初めて行うべきです。

消去は受信箱からメールを削除するか、受信箱ごと消します。テストが必要とする理由は二つあります。新しいアドレスを作らずに試行の間でリセットすることと、ケースの終了時に片付けることです。

待機やロングポーリングのエンドポイントを足すサービスもあります。メールが届くかタイムアウトするまで接続を保持します。便利ですが、クライアントは一覧に戻れるべきです。待機の呼び出しは最もレート制限に遭いやすい部分だからです。

不安定さを出さずにコードをポーリングするには?

この種のテストで最もよくある間違いは固定の待ち時間です。一定の秒数は当て推量で、配送が遅ければ短すぎ、速ければ無駄に長く、負荷の高い CI マシンではどちらにも外れます。一覧を呼び、一致を確認し、見つかり次第すぐ返すループに置き換え、上限を設けて、ジョブを止めるのではなくテストを失敗させます。

一致の判定は問題の残り半分です。テストが求めるのは、ケースが作ったアドレス宛のメールであり、受信箱に複数の種類のメールが入り得るなら、件名に安定した断片を含むものです。一致が複数あるときは最新を選び、再試行による重複配信が読み取りを乱さないようにします。無条件に最初の一件を取ってはいけません。アドレスを使い回す場合、それこそが古いコードを検証してしまう方法です。

抽出には足場が要ります。本文には参照番号、日時、価格が含まれることがあり、最初の数字の並びをつかむ解析器はときどきそれらを拾ってしまいます。コードを導く文言を探し、その近くからコードを読み、何も一致しなければ本文を添えて失敗させます。

最後に、再送の制限を尊重します。コードの流れは通常、短い時間枠で数回しか送信を許しません。その制限はテスト対象の挙動の一部です。新しいコードを得ようとボタンをもう一度押すテストは、いずれ拒否され、誤った理由で失敗します。再試行は、メールをもう一度読むことであり、別のメールを誘発することではありません。

エンドツーエンドや CI にどう組み込むか?

きれいな形はフィクスチャです。流れが始まる前にフィクスチャが受信箱を作ってアドレスを返します。テストはそのアドレスでアプリを操作します。アプリが送信済みだと確認したら、アサーションが受信箱を読んでコードを取り出します。ケースが終わればフィクスチャが受信箱を削除します。

クライアントは小さく、差し替え可能に保ちます。一つのモジュールが四つの呼び出しを包み、テストは生の HTTP ではなくそのモジュールに依存します。これにより、単体テストでは偽物に差し替えられ、同じスイートをアサーションを書き換えずに別の提供者へ向けられます。

CI では、資格情報はジョブのシークレットストアに置き、リポジトリにもログ行にも決して入れません。ジョブごと、または並列ワーカーごとに専用の受信箱を与え、生成したアドレスには実行を識別する接頭辞を付けます。迷子のメールを目で見て帰属できるようにするためです。クライアントのタイムアウトはジョブ自体のタイムアウトより短くします。止まったポーリングが、突然のジョブ打ち切りではなく明確なメッセージで失敗するようにするためです。

再試行するのは読み取りであり、流れ全体ではありません。コードがまだ届いていなければ、待ってからもう一度読みます。サインアップを再実行すると二通目のメールが生まれ、アサーションの候補がもう一つ増えるだけです。そして、メールボックス API を本番の流れに入れないでください。テスト基盤であり、スイートが本物の顧客へ送れるようになってはいけません。

コードを囲む流れそのものは、読み取りの仕組みではなくメール確認フローのテストで扱っており、解析の工程はエンドツーエンドテストの OTPで詳しく説明しています。

分離と後片付け

ケースごとに一つのアドレスが、ほとんどのケース間の失敗を防ぐ原則です。どのメールが誰のものかを考える必要がなくなり、受信箱は一つのケースの通信しか受け取っていないため、新しさの問題も消えます。

後片付けは明示的に、無条件に行います。成功経路だけでなく、ケースが通っても失敗しても走る後処理で受信箱を削除します。提供者の有効期限だけに頼るのは誤りです。メールは同じマシン上の後の実行に読まれるほど長く残ることがあり、その期限は便宜であって保証ではありません。

片付けに失敗したら、記録してスイートは最後まで走らせます。片付けのエラーは知る価値がありますが、製品の欠陥と同じではありません。それで実行を失敗させると、チームは後処理の失敗を無視するようになります。アドレスが受け取ったものはすべてテストデータとして扱います。一つのアサーションのために存在し、外部へ出したり共有したりせず、誰かの連絡先として扱ってもいけません。

制限と注意点

メールボックス API は依然として第三者の依存であり、その制限はあなたのテストの制限になります。毎分のレート制限は、大規模な並列実行からの作成の集中を拒むことがあります。割り当ては同時に存在できるアドレス数を制限します。メールは遅延することがあり、遅延したメールは届くまで失われたものと全く同じに見えます。

使い捨てドメインは広くブロックされています。提供者のドメインは、まさにテストしている登録フォームに拒否されることがあり、正当なテストを見当違いの失敗に変えます。そのときの答えは、提供者を特例扱いすることではなく、テスト対象の製品が使い捨てアドレスを意図的に拒むのかを見極め、その挙動を意図的にテストすることです。

正直なまとめです。メールボックス API は到着したものを主張するのに適した道具です。アプリが送信したものを主張するには、ローカルの受信エンドポイントの方が速く、割り当てもありません。成熟したスイートはふつう両方を使います。大半のアサーションはローカル取り込みで、本物の配送経路そのものがテスト対象のときだけメールボックス API を使います。

次の一歩

共有の受信箱をポーリングしてコードを読むテストを見つけ、メールボックス API で新しいアドレスを作るフィクスチャに置き換えてください。アドレスを実行と一緒にログへ残し、後処理で削除し、これまで我慢していた不安定さのうちどれだけが消えるかを見てください。手作業で本物の受信箱が要るときは、一時メールのページがすぐに一つ作ります。そこで配られるアドレスは一回の実行の足場であり、本物の身元ではありません。

続けて読む

使い捨てメール(一時メール・10分メール)の関連記事