FIFOキューの『コンテンツに基づく重複排除』について
SQSが絡むテストを自動化する場合、テストプログラムを作る前に以下を確認してください。
- テスト対象のモジュールが使っているSQSキューはFIFOキューである。
- そのFIFOキューは『コンテンツに基づく重複排除』がONである。
- 自動化しようとしている複数のテストケースの中で、完全に同じメッセージが送信されるケースが2つ以上存在する。
上記全てに該当する場合、テストプログラムを作っても想定通りに動かない可能性が高いです。
『コンテンツに基づく重複排除』がONのFIFOキューは、内容が全く同じメッセージを5分以内に受信しても、最初の1件しか配信しないからです。なので短時間中に本文が同じメッセージを複数回送るようなテストプログラムは、2件目以降が空振りしてしまいます。
どうしてもテスト自動化したい場合は、全ケースで必ず異なるメッセージが送信されるようにテストケースを作るとか、そもそも『コンテンツに基づく重複排除』を使う必要があるのか検討するとか、別方面での工夫が必要になります。
(テスト中だけ『コンテンツに基づく重複排除』をOFFにしようとしても、『コンテンツに基づく重複排除』をOFFにすると、今度はメッセージ送信時にパラメータで『重複排除ID (MessageDeduplicationId)』を指定しないといけなくなります。テスト対象モジュールがそれに対応した作りになっていない限り、これも無理です。)
では、次項から本題です。
npmでaws-sdkをインストール
Node.jsでSQSキューにアクセスするには、npmパッケージのaws-sdkが必要です。
テストプログラム用のプロジェクト内で以下コマンドを実行すると、プロジェクト内にaws-sdkの最新バージョンがインストールされます。
この記事を書いた時に使ってたやつは、バージョンaws-sdk@2.402.0でした。
また、aws-sdkを利用するには開発環境にAWSの認証情報を設定する必要があるので、設定してない場合は設定します。方法は以下の公式マニュアルの『ステップ 1: 認証情報を設定する』を参照してください。
Node.js での使用開始 - AWS SDK for JavaScript
キューにメッセージを投入する方法
初期データとして、テストプログラムからキューにメッセージを投入したいことがあります。メッセージの投入には SQS.sendMessage()
を使います。
投入先のキューがFIFOキューの場合、パラメータにグループID (MessageGroupId) が必要です。また、FIFOキューの中でも『コンテンツに基づく重複排除』がONの場合、さらに重複排除ID (MessageDeduplicationId) が必要になります。テスト対象のモジュールが使うキューに合わせて設定してください。
例えば before()
で行うなら、以下のようにします。
キューをカラにする方法
テスト前など、キューをカラにしたいことがよくあります。
キューをカラにするメソッドとしては SQS.purgeQueue()
というのがありますが、これは削除に最大60秒かかるらしいので、使ったことありません。私は単純に SQS.receiveMessage()
で10件ずつ取り出して、全部 SQS.deleteMessage()
で消してます。
例えば before()
で行うなら、以下のようにします。
また、これも私は使ったことありませんが、SQS.deleteMessageBatch()
というのもあるので、そっちを使えばもっとリクエスト回数を減らせるかもしれないです。
メッセージが投入されており、想定通りの内容であることのテスト
メッセージの取得には SQS.receiveMessage()
を使います。
取得する際、メッセージの件数が想定通りであることを確認するために、パラメータの MaxNumberOfMessages
を想定されるメッセージ件数より多く設定します。キューに投入した後すぐに取り出そうとすると空振りすることがあるので、WaitTimeSeconds
も設定してロングポーリングさせると確実です。
それから、メッセージの内容の正しい正しくないに関わらず、受信したメッセージは即座に削除します。メッセージを削除しない場合、テストプログラム内で取得したメッセージが『処理中』状態のまま残り、可視性タイムアウトが経過した後でキューに戻ってきてしまうからです。
以下のサンプルでは、テスト対象のモジュールを実行した体でキューに適当なメッセージを投入し、改めてそれを取得して検証しています。
なお、ここではメッセージ内容の細かい検証は行わず、expect().deep.equal()
一撃でやってしまってます。もっと細かい検証方法は基本編やWebAPI編に書いてるので、よかったら読んでみてください。
キューがカラであることのテスト
SQS.receiveMessage()
で取得し、戻りに Messages
キーが含まれていないことを確認するだけです。
この場合も、もしメッセージが取得できてしまったら必ず消しておきます。消す前に内容をコンソールに出力しておくと、何が誤って送信されてしまったのか分かって便利です。
以上
以上でAmazon SQS編は終わりです。次はAWS DynamoDB編です。これもう何やっても、データ投入方法と取得方法が違うだけですね。でもたぶん書くと思います。