WebhookとAsync Workflowのテスト:SaaSテストで最も難しい部分

Webhookは現代のSaaSの配管です。Stripeは決済イベントを送信します。GitHubはプッシュイベントを送信します。Slackはメッセージイベントを送信します。アプリケーションはこれらをバックグラウンドで処理し、ユーザー操作なしで状態を更新します。
Webhookのテストは難しいことで知られています。イベントは外部サービスから来ます。非同期で届きます。順序が前後したり、重複したり、サイレントに失敗したりする可能性があります。従来のE2Eテストフレームワークは、このような用途を想定して設計されていません。
Webhookテストが難しい理由
UIトリガーがない。ほとんどのE2Eテストはユーザー操作(ボタンのクリック、フォームの入力)から始まります。Webhookはバックグラウンドで動作します。Stripeの決済イベントをトリガーするボタンは存在しません。
非同期処理。Webhookが届き、ハンドラーが処理し、結果がデータベースやUIに反映されるまでに時間がかかります。テストはこのタイミングのずれに対処しつつ、不安定にならない必要があります。
外部依存。WebhookはStripe、GitHubなどの外部サービスから送られます。テスト環境では、実際のサービスのテストモードイベントか、Webhookシミュレーターのいずれかが必要です。
冪等性の要件。Webhookプロバイダーは重複イベントを送信することがあります。ハンドラーは重複レコードを作成せずに正しく処理しなければなりません。
Webhookテストの実践的なアプローチ
アプローチ1:ハンドラーを直接テストする。サンプルペイロードを使ってWebhookハンドラーを呼び出すユニットテストを書きます。これによりハンドラーのロジックを検証できますが、統合上の問題(シグネチャ検証、HTTPパーシング、データベースへの書き込み)は見逃します。
アプローチ2:アプリケーションを通じてテストする。Webhookを発生させるアクション(例:Stripeのテスト決済を完了する)をトリガーし、アプリケーションの状態が正しく更新されたことを確認する。包括的な手法だが、外部サービスのテストモードが必要となる。
アプローチ3:観測可能な結果をテストする。Webhookハンドラー自体をテストするのではなく、Webhookが発火した後に正しい状態になっているかをテストする。決済Webhookでサブスクリプションが有効化されるべきなら、決済フロー完了後にユーザーが有料機能にアクセスできることを確認する。
TestSpriteはデフォルトでアプローチ3を採用している。バックグラウンド処理の結果を含む完全なユーザーフローをテストし、決済フロー後にはサブスクリプションの有効化を、フォーム送信後にはメール配信の効果を検証する。非同期処理は、その観測可能な結果を通じてテストされる。
Webhookを多用するSaaSアプリケーションにおいて、このアプローチは本当に重要なバグを捉える。有効化されなかったサブスクリプション、送信されなかった通知、同期されなかったデータなどがその例だ。
TestSpriteを無料で試す →