メインコンテンツまでスキップ

ローカル実行によるデバッグとテスト

アプリケーションコードをローカル開発環境で実行しデバッグを行う方法とテストの方法を記載したドキュメントです。

概要

AWS Lambda は Amazon API Gateway 起動(Web API)でも Event 起動でも同じく handler 関数の第一引数 event に処理に必要なデータが入っています。この Event Payload をあらかじめ作成してローカル起動することで Lambda の動きを再現します。

処理の中で Amazon DynamoDB や S3 など他の AWS サービスと連携する場合は、AWS Lambda 実行ロールの代わりにローカル環境にセットされている AWS 認証情報( 環境変数のアクセスキー または ~/.aws/credentials )が利用されます。

以下よりイベントペイロードを指定する例を確認いただけます。

  • WebAPI ロジック

    • API Gateway (REST API) から渡されるAPI呼び出しのリクエストペイロードを直接指定し、ハンドラー関数を実行しています。
      • src/.local.sample_api.get_users.py
      • src/.local.sample_api.post_users.py
  • Event 起動

    • S3・SNS・SQSなどから渡されるイベントペイロードを直接指定し、ハンドラー関数を実行しています。
      • src/.local.sample_event.import_users.py

イベントペイロードのテンプレートは、AWS Lambda のコンソールから取得できます。S3 イベントの場合「S3 Put」、API Gateway (REST API) の場合は「API Gateway AWS Proxy」を選択してください。

ローカル実行の手順

※「ローカル環境」とは、本カタログで立ち上げた EC2 インスタンスの環境を指します。

1. Dockerの立ち上げ

ローカル開発は専用のpythonスクリプトと、PostgreSQLのコンテナ及びS3の互換ストレージであるMinIOのコンテナを使って行います。まずはdocker-compose.yamlに定義されているこれらのコンテナを起動しましょう。

[ec2-user ~]docker compose up -d

2. Table作成

コンテナで起動したPostgreSQL内にデータベースとテーブルを作成します。以下のPythonスクリプトでデータベースとusersテーブルをコンテナ内に自動作成してくれます。

[ec2-user ~]poetry run python ./src/.init_db.py

psqlというPostgreSQLのコマンドラインツールもインストール済みなのでそれを使ってコンテナ内のテーブルの操作を行うことも可能です。ここでは3件データを作成しています。パスワードが求められますが、password と入力してください。

[ec2-user ~]psql -h localhost -U admin -d mydb

mydb=# INSERT INTO users (name, country, age) VALUES
('Alice', 'Japan', 30),
('Bob', 'USA', 25),
('Charlie', 'Germany', 35);

mydb=# exit #これで通常のターミナルに戻れます

3. APIのローカル実行

GETのAPI

.local.sample_api.get_users.py はGETメソッドでユーザデータを取得するAPIをシュミレートしたPythonスクリプトです。generate_http_api_request_payload という関数で擬似的にAPI Gatewayのイベントを生成しています。ファイル内の以下の箇所を変更するとAPIからクエリストリングでリクエストを送る内容を変えながら開発可能です。

QUERY_PARAMS  = {
'id': '1'
}
[ec2-user ~]poetry run python ./src/.local.sample_api.get_users.py
API Execution Result: {"statusCode": 200, "body": "{\"statusCode\":200,\"body\":{\"name\":\"Alice\",\"country\":\"Japan\",\"age\":30}}", "isBase64Encoded": false, "headers": {"Content-Type": "application/json"}, "cookies": []}

実際にスクリプトを走らせるとAPIからのレスポンスが返ってきます。

POSTのAPI

.local.sample_api.post_users.py はPOSTメソッドでユーザを作成するAPIをシュミレートします。同様にgenerate_http_api_request_payload という関数で擬似的にAPI Gatewayのイベントを生成しています。今回は以下Bodyパラメータを操作しながら開発が可能です。

BODY = {
"name": "Shigeo",
"country": "Japan",
"age": 30
}

実際にスクリプトを実行すると正しくBodyに設定されたデータが作成されていることが分かります。

[ec2-user ~]poetry run python ./src/.local.sample_api.post_users.py
API Execution Result: {"statusCode": 200, "body": "{\"statusCode\":200,\"body\":{\"message\":\"The data created successfully.\"}}", "isBase64Encoded": false, "headers": {"Content-Type": "application/json"}, "cookies": []}

$ mydb=# SELECT * FROM users WHERE id=4;
id | name | country | age
----+--------+---------+-----
4 | Shigeo | Japan | 30
(1 row)

4. S3イベントのローカル実行

S3イベントではMinIOというS3互換ストレージを使ってテストします。以下スクリプトを実行するとMinIO上にtest-bucketというバケットを作成して、sample_users.csvをアップロードします。

[ec2-user ~]poetry run python ./src/.init_MinIO.py

MinIOでは直接Lambdaをトリガーするところまでは再現できません。なので、.local.sample_event.import_users.py 内のgenerate_s3_request_payload でLambdaがトリガーされた時のイベントを生成し、ローカル実行を可能としています。スクリプトを実行するとsample_users.csvの内容がDB内に生成されていることが分かります。

[ec2-user ~]poetry run python ./src/.local.sample_event.import_users.py
mydb=# SELECT * FROM users;
id | name | country | age
----+---------+---------+-----
1 | Alice | Japan | 30
2 | Bob | USA | 25
3 | Charlie | Germany | 35
4 | Shigeo | Japan | 30
5 | Taro | Japan | 30
6 | Alice | USA | 28
7 | Bob | UK | 35
8 | Maria | Germany | 25
9 | Li | China | 32

5. ユニットテスト

ユニットテストもサンプルの実装を提供しています。pytestを使って、testsディレクトリの配下にテストコードが配置されています。ユニットテストも同様にPostgreSQLとMinIOのコンテナを使って、バリデーションのパターンや正常系のパターンなど必要と思われるテストケースを実装しています。

テストは以下のコマンドで実行できます。

[ec2-user ~]poetry run pytest

その他のテスト方法

ローカル環境で擬似的な環境を立ち上げる

WebAPI ロジックの場合、SAM Local ( start-api ) を利用して localhost にて Amazon API Gateway をエミュレーションした API サーバーを立ち上げることが可能です。

Event 起動の場合、以下のようなものでローカル環境で AWS サービスをエミュレーションしてテスト等を行うことが可能です。