Open4
AWS Lambda
PythonでSQSのアプリ作成
プロジェクトの作成
sam initでテンプレートを作成する。
sam init
SQSの定義を追加。
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
PackageType: Image
Events:
MySQSEvent:
Type: SQS
Properties:
Queue: !GetAtt MySqsQueue.Arn
BatchSize: 1
Metadata:
Dockerfile: Dockerfile
DockerContext: ./make_queue
DockerTag: python3.8-v1
MySqsQueue:
Type: AWS::SQS::Queue
ローカル稼働
SAMのgenerate-event
機能を利用してテスト用のEvent情報を作成する。
% sam local generate-event sqs receive-message
{
"Records": [
{
"messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
"receiptHandle": "MessageReceiptHandle",
"body": "Hello from SQS!",
"attributes": {
"ApproximateReceiveCount": "1",
"SentTimestamp": "1523232000000",
"SenderId": "123456789012",
"ApproximateFirstReceiveTimestamp": "1523232000001"
},
"messageAttributes": {},
"md5OfBody": "7b270e59b47ff90a553787216d55d91d",
"eventSource": "aws:sqs",
"eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue",
"awsRegion": "us-east-1"
}
]
}
あとはsam local invoke
機能を使ってLambdaのローカル稼働を実施する。
-e
オプションで指定したEvent情報のファイルをインプットとして稼働ができる。
% sam local invoke HelloWorldFunction -e ./events/sqs.json
Invoking Container created from helloworldfunction:python3.8-v1
Building image..........
Skip pulling image and use local one: helloworldfunction:rapid-1.19.1.
START RequestId: d830ac67-0913-4a78-bb40-4de79086c077 Version: $LATEST
END RequestId: d830ac67-0913-4a78-bb40-4de79086c077
REPORT RequestId: d830ac67-0913-4a78-bb40-4de79086c077 Init Duration: 0.13 ms Duration: 125.69 ms Billed Duration: 200 ms Memory Size: 128 MB Max Memory Used: 128 MB
{"statusCode": 200, "body": "{\"messages\": [\"Hello from SQS!\"], \"input\": {\"Records\": [{\"messageId\": \"19dd0b57-b21e-4ac1-bd88-01bbb068cb78\", \"receiptHandle\": \"MessageReceiptHandle\", \"body\": \"Hello from SQS!\", \"attributes\": {\"ApproximateReceiveCount\": \"1\", \"SentTimestamp\": \"1523232000000\", \"SenderId\": \"123456789012\", \"ApproximateFirstReceiveTimestamp\": \"1523232000001\"}, \"messageAttributes\": {}, \"md5OfBody\": \"7b270e59b47ff90a553787216d55d91d\", \"eventSource\": \"aws:sqs\", \"eventSourceARN\": \"arn:aws:sqs:us-east-1:123456789012:MyQueue\", \"awsRegion\": \"us-east-1\"}]}}"}
参考資料
Lambdaにテストの追加
importの問題
以下のディレクトリ構成の時
.
├── .aws-sam
│ └── build.toml
├── .gitignore
├── README.md
├── __init__.py
├── events
│ ├── event.json
│ └── sqs.json
├── poetry.lock
├── pyproject.toml
├── src
│ ├── beer
│ │ ├── Dockerfile
│ │ ├── __init__.py
│ │ └── app.py
│ └── twitter_to_db
│ ├── Dockerfile
│ ├── __init__.py
│ ├── app.py
│ └── requirements.txt
├── template.yaml
└── tests
├── __init__.py
└── unit
├── __init__.py
├── _test_handler.py
├── get_beer_data
│ └── __init__.py
└── test_get_beer_data.py
以下の通りpython -mをつけるとテスト対象のモジュールのimportが行える。
python -m をつけるとルートディレクトリの設定が変わる?
# pytestを直接実行した時
$ pytest tests
...
E ModuleNotFoundError: No module named 'src'
================================================================== 1 error in 0.05s ==================================================================
# python -mをつけた時
$ python -m pytest t
...
E ModuleNotFoundError: No module named 'boto3'
============================================================== short test summary info ===============================================================
ERROR tests/unit/test_get_beer_data.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
================================================================== 1 error in 0.06s ==================================================================
この方法もある
Testing AWS CDK and Lambda Functions with pytest
参考資料
テスト全般
- Unit、Integration
- コード単位
- Function単位
- sam local start-lambdaを使ってFunctionを起動する
Lambda自体を呼び出す
レスポンスの結果から以下のようにしてLambdaからReturnされた値にアクセスできる。
response = boto3.client('lambda').invoke(
FunctionName='test0820',
InvocationType='RequestResponse',
Payload=Payload
)
body = json.loads(response['Payload'].read())
参考資料
- Testing AWS CDK and Lambda Functions with pytest
- pytest, SAM, LocalStackを使ったAWS Lambda結合テスト - public note
- How I Write Meaningful Tests for AWS Lambda Functions | by Paul Singman | Towards Data Science
- Integrating with automated tests - AWS Serverless Application Model
- boto3からDynamoDBへのアクセスをmotoでモックしてみる