Chaliceで記述したLambda関数を呼んでテストを実行することができます。通常Lambdaで扱う処理はAWSリソースを扱うため、その部分に関してはモック化する必要があります。Lambda関数の呼び方と、AWSリソースを扱っている箇所のモック化について解説します。
テストフレームワークの選定
Chaliceはテストの種類を選びません。通常、標準パッケージのunittest
かサードパーティ製のpytest
を利用します。
pytestを利用する場合はpip install pytest
でpytest
をインストールしておきます。
Lambdaに共通したテストの書き方
例えばapp.pyに下記のようなLambda関数がある場合のテストを書く場合です。
from chalice import Chalice
app = Chalice(app_name="sample")
@app.route("/hello", methods=["POST"])
def hello():
print("hello world!!")
return {"message": "world"}
app.pyと同階層にtests
というディレクトリを作成します。
その中に__init__.py
というファイルを作成します。
mkdir tests
touch tests/__init__.py
unittestの場合
testsディレクトリの中にtest_app.py
を作成します。
import unittest
from chalice.test import Client
from app import app
class TestLambdaFunc(unittest.TestCase):
def test_func(self):
with Client(app) as client:
# TODO:ここでLambda関数を呼び出す
# 下記はAPIのPOSTの例
actual = {"message": "world"}
response = client.http.post("/hello")
self.assertEqual(response.json_body, actual)
pytestの場合
testsディレクトリの中にtest_app.py
を作成します。
unittest
と異なり、ファイル名や関数名に決まりがありますので注意してください。
詳細についてはpytest
のドキュメントを参照してください。
from chalice.test import Client
from app import app
def test_func():
with Client(app) as client:
# TODO:ここでLambda関数を呼び出す
# 下記はAPIのPOSTの例
actual = {"message": "world"}
response = client.http.post("/hello")
assert response.json_body == actual
モック化
unittest
ライブラリのmockオブジェクトを利用します。
下記はpytest
でprintを呼び出している箇所をモック化する例です。
from unittest import mock
from chalice.test import Client
from app import app
@mock.patch("app.print")
def test_func(mock_print: mock.MagicMock):
with Client(app) as client:
actual = {"message": "world"}
response = client.http.post("/hello")
assert response.json_body == actual
mock_print.assert_called_once_with("hello world!!")
Lambdaの種類に対応するテスト関数
前の項ではclient.http.post
を使用しましたが、これはRESTAPIのPOSTを検査する場合に使用します。他にもLambdaの種類に対応しています。最新の情報は下記のリンクから参照ください。
- 単独のLambda関数を呼ぶ:
client.lambda_.invoke("myfunction")
- RESTAPIを呼ぶ:
- client.http.request
- client.http.get
- client.http.post
- client.http.put
- client.http.delete
- client.http.patch
- client.http.option
- client.http.head
上記以外のイベントはinvokeメソッドの引数に対応するイベントのインスタンスを作成して渡します。
SNSイベントの例
result = client.lambda_.invoke(
"my_sns_handler",
client.events.generate_sns_event("Hello world")
)
- SNSイベント:generate_sns_event
- S3イベント:generate_s3_event(※CDKでは利用しません)
- SQSイベント:generate_sqs_event
- CloudWatchイベント:generate_cw_event
- Kinesisイベント:generate_kinesis_event