はじめに
Lambdaの単体テストを実行したい際に、実際のAWSリソースを使用せずにローカルで確認をしたい場合があります。本記事では、pytest
、moto
、boto3
を使用してローカル環境でAWS Lambdaの動作テストを本記事では実装します。
ゴール
- AWS LambdaからDynamoDBのテーブルに対して、データを読み書きする処理をローカルでテストしたい
- モックを使って簡単にUTしたい
環境構築
pip install pytest moto boto3
上記のパッケージがすでにインストールされているか確認したい場合は下記のコマンドになります。
pip list | findstr "boto3 moto pytest"
Lambdaのモックを作成
テストの対象となるLambdaのスクリプトを準備します。
環境変数も使用せず、処理の流れも DBにデータを書き込み⇒書き込んだデータを取得する
だけのシンプルなものです。
import json
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('test-table')
def lambda_handler(event, context):
item = {
'id': event['id'],
'name': event['name']
}
# DynamoDBに接続してデータを書き込み
table.put_item(Item=item)
# 書き込んだデータを取得
response = table.get_item(Key={'id': event['id']})
return {
'statusCode': 200,
'body': json.dumps(response['Item'])
}
テストコードを作成
import json
import boto3
import pytest
from moto import mock_aws
from lambda_function import lambda_handler
# DynamoDBのモックテーブル作成
dynamodb = boto3.resource('dynamodb')
@mock_aws
def test_lambda_function():
table = dynamodb.create_table(
TableName='test-table',
KeySchema=[{'AttributeName': 'id', 'KeyType': 'HASH'}],
AttributeDefinitions=[{'AttributeName': 'id', 'AttributeType': 'S'}],
BillingMode='PAY_PER_REQUEST'
)
# Lambdaに渡すテストデータ
event = {
'id': '1',
'name': 'test'
}
# テストデータでLambda関数実行
result = lambda_handler(event, None)
# statusCodeが200か評価
assert result['statusCode'] == 200
body = json.loads(result['body'])
# テーブルから取得した値(name)が'test'か評価
assert body['name'] == 'test'
動作確認
動作確認のためテストを実行します。
# 詳細情報を表示して実行
pytest test_lambda_function.py -v
テストが成功すれば下記のように出力されます。
=================================================== test session starts ====================================================
~~~~
test_lambda_function.py::test_lambda_function PASSED [100%]
==================================================== 1 passed in 0.62s =====================================================
カバレッジを出力したい場合は、pytest-cov
を使用するとカバレッジを出せます。