Step Functionsをローカル環境でテストできるStep Functions Localのモックサービス統合機能がリリースされたので試してみた
上記の記事で紹介されていた Step Functions をローカル環境で実行する方法を実際にためしてみました。
Step Functions Local について
従来、AWS Lambda や Amazon SQS と連携した Step Functions をテストするには実際の AWS リソースのエンドポイントを叩く必要がありました。Step Functions Local ではローカル環境で Lambda などのサービスのレスポンスをモックすることで完全に隔離された環境で Step Functions の動作確認を行うことができます。
本記事の大まかな流れ
- SAM のサンプルプロジェクトを Pull
- Docker 環境でテストを実行
サンプルプロジェクトはaws-samplesのレポジトリに用意してあるものを利用します。テストに利用するテストケースとモックレスポンスも全てサンプルレポジトリのものを利用するので写経する必要はありません。
サンプルプロジェクトの概要
レポジトリの README の説明と重複しますが大まかに説明すると、カスタマーのコメントを感情分析してポジティブなもののみDynamoDBに保存、ネガティブなもの、住所やidentityなどの情報が不足しているものはDBには保存されずEvent Bridgeに送られる
というものです。
テストしたい内容
- Identity(メールアドレスと顧客 ID) と住所の認識に成功したか
- Comprehend.DetectSentiment API を実行した後、ポジティブなセンチメントが検出されたか
- DynamoDB への書き込みが成功したか
- Event Bridge の Event Bus に正常にイベントがパブリッシュされたか
mock configuration file を記述
モックで返したい場所のレスポンス内容を JSON 形式で記述します。
以下はカスタマーのIdentityが有効かどうか
を返却する Lambda のモックレスポンスの例です。
Step Functions Local は返却値の形式のバリデーションはできないため、AWS ドキュメントに記載されているレスポンス形式をモックに記述する必要があります。 以下は Lambda 関数の返り値をモックしたものですが、内容は Lambda のレスポンス形式に沿っている必要があります。レスポンスの形式を確認する手取り早い手段として実際の API を CLI から呼び出してレスポンスの形式を確かめる方法があります。
"CheckIdentityLambdaMockedSuccess": { "0": { "Return": { "StatusCode": 200, "Payload": { "statusCode": 200, "body": "{\"approved\":true,\"message\":\"identity validation passed\"}" } } } }
参考元:aws-stepfunctions-examples
感情分析の処理のモック
次にカスタマーのコメントがポジティブなものかを判別する AWS Comprehend を使った感情分析処理のモックレスポンスを以下のように記述します。 AWS Comprehend API の返り値の形式はこちらを参考にしてください。
"DetectSentimentRetryOnErrorWithSuccess": { "0-2": { "Throw": { "Error": "InternalServerException", "Cause": "Server Exception while calling DetectSentiment API in Comprehend Service" } }, "3": { "Return": { "Sentiment": "POSITIVE", "SentimentScore": { "Mixed": 0.00012647535, "Negative": 0.00008031699, "Neutral": 0.0051454515, "Positive": 0.9946478 } } } }
テストケースを定義
モックレスポンスの定義が完了したので次にテストケースを定義します。モック内容の全文はこちらを参照してください。
"RetryOnServiceExceptionTest": { "Check Identity": "CheckIdentityLambdaMockedSuccess", "Check Address": "CheckAddressLambdaMockedSuccess", "DetectSentiment": "DetectSentimentRetryOnErrorWithSuccess", "Add to FollowUp": "AddToFollowUpSuccess", "CustomerAddedToFollowup": "CustomerAddedToFollowupSuccess" }
ここまでがテストケースとモックデータの大まかな説明です。次は実際にサンプルプロジェクトのソースコードを使って Step Functions Local を動かしてみます。
レポジトリをクローン
レポジトリからサンプルプロジェクトを Pull します。
git clone https://github.com/aws-samples/aws-stepfunctions-examples.git # app-local-testing-mock-config/へ移動 cd aws-stepfunctions-examples/sam/app-local-testing-mock-config
Docker を起動
Step Functions Local の Docker Image を Pull します。 Docker の Daemon が起動していることを確認して以下のコマンドを実行してください。
docker pull amazon/aws-stepfunctions-local
次に Docker Run を実行します。
docker run -p 8083:8083 \ --mount type=bind,readonly,source=$(pwd)/statemachine/test/MockConfigFile.json,destination=/home/StepFunctionsLocal/MockConfigFile.json \ -e SFN_MOCK_CONFIG="/home/StepFunctionsLocal/MockConfigFile.json" \ amazon/aws-stepfunctions-local
Step Functions Local の State Machine を作成
Docker が起動した状態で以下のコマンドを実行してモックに利用する State Machine を作成します。
aws stepfunctions create-state-machine \ --endpoint-url http://localhost:8083 \ --definition file://statemachine/local_testing.asl.json \ --name "LocalTesting" \ --role-arn "arn:aws:iam::123456789012:role/DummyRole"
以下のレスポンスが返るので、この State Machine の ARN を利用して Step Functions Local でテストを実行します。
{ "stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:LocalTesting", "creationDate": "2022-02-08T01:15:39.239000+09:00" }
HappyPath のテストを実行
正常系のテストを実行します。期待する結果はカスタマーのidentityと住所が入力されている、ポジティブな内容のコメントを検知、FollowUpのDynamoDBにカスタマーのデータを格納するCustomerAddedToFollowupが呼び出される
、です。
aws stepfunctions start-execution \ --endpoint http://localhost:8083 \ --name executionWithHappyPathMockedServices \ --state-machine arn:aws:states:us-east-1:123456789012:stateMachine:LocalTesting#HappyPathTest \ --input file://events/sfn_valid_input.json
--input
には正常系のサンプルデータを渡しています。
sfn_valid_input.json
{ "data": { "firstname": "Jane", "lastname": "Doe", "identity": { "email": "jdoe@example.com", "ssn": "123-45-6789" }, "address": { "street": "123 Main St", "city": "Columbus", "state": "OH", "zip": "43219" }, "comments": "I am glad to sign-up for this service. Looking forward to different options." } }
結果を確認する
Identication と住所の識別に成功し、感情分析でポジティブなコメントを認識したのちに呼び出される想定の関数、CustomerAddedToFollowup
の処理がちゃんと呼び出されたかを以下のコマンドで確認します。
aws stepfunctions get-execution-history \ --endpoint http://localhost:8083 \ --execution-arn arn:aws:states:us-east-1:123456789012:execution:LocalTesting:executionWithHappyPathMockedServices \ --query 'events[?type==`TaskStateExited` && stateExitedEventDetails.name==`CustomerAddedToFollowup`]'
レスポンスは以下です。
[ { "timestamp": "2022-02-08T01:19:32.611000+09:00", "type": "TaskStateExited", "id": 32, "previousEventId": 31, "stateExitedEventDetails": { "name": "CustomerAddedToFollowup", "output": "{\"StatusCode\":200,\"Payload\":{\"statusCode\":200}}", "outputDetails": { "truncated": false } } } ]
CustomerAddedToFollowup
が呼び出されたことが確認できました。
Negative Path のテストを実行
次に、感情分析の結果がネガティブだった場合を想定したテストを実行してみましょう。想定する結果はNegativeSentimentDetected
が呼ばれていることです。
aws stepfunctions start-execution \ --endpoint http://localhost:8083 \ --name executionWithNegativeSentimentMockedServices \ --state-machine arn:aws:states:us-east-1:123456789012:stateMachine:LocalTesting#NegativeSentimentTest \ --input file://events/sfn_valid_input.json
レスポンスを確認します。
aws stepfunctions get-execution-history \ --endpoint http://localhost:8083 \ --execution-arn arn:aws:states:us-east-1:123456789012:execution:LocalTesting:executionWithNegativeSentimentMockedServices \ --query 'events[?type==`TaskStateExited` && stateExitedEventDetails.name==`NegativeSentimentDetected`]'
結果:
[ { "timestamp": "2022-02-08T01:39:51.073000+09:00", "type": "TaskStateExited", "id": 27, "previousEventId": 26, "stateExitedEventDetails": { "name": "NegativeSentimentDetected", "output": "{\"Payload\":{\"Entries\":[{\"EventId\":\"abc123\"}],\"FailedEntryCount\":0}}", "outputDetails": { "truncated": false } } } ]