Python転職初心者向けエンジニアリングブログ

Pythonに魅了されたあなたへ。エンジニアリングの扉を開く転職初心者向けのブログへようこそ。このブログでは、Pythonの奥深さに迫りながら、エンジニアリングへの転職に役立つ情報を提供しています。未経験者から始めるPythonエンジニアリングの世界への一歩を踏み出すためのガイダンス、ベストプラクティス、そして成功事例など、初心者の方でもわかりやすいコンテンツをお届けします。

pytestとmotoでLambdaを呼び出そう!~ 初心者でも簡単にテストできる ~

LYPプレミアム会員 python

みなさん、こんにちは!AWS Lambdaを使っている方、テストの仕方で悩んだことありませんか?Lambdaはイベント駆動型のサーバーレスコンピューティングサービスで、いろいろな使い方ができるんですが、実際にそのLambda関数がうまく動作しているかどうか、手動で確認するのは結構面倒ですよね。そこで今回は、Pythonのテストフレームワークであるpytestと、AWSサービスをモックしてくれる便利なライブラリmotoを使ってLambdaを呼び出す方法を紹介します!

テストを書くのはちょっと…という方も、心配しないでください。テストを書くことで、コードの品質が向上し、変更を加えた際の不具合をすぐに見つけられるようになるんです。少しずつ、コツを掴んでいきましょう!

それでは、早速やってみましょう!

Lambda関数を作成しよう

まずは、AWS Lambdaの簡単な関数を作成しましょう。今回は、2つの数値を受け取って、その合計を返すLambda関数を作成します。コードは以下のようになります。

import json

def lambda_handler(event, context):
    num1 = event.get("num1")
    num2 = event.get("num2")
    
    if num1 is None or num2 is None:
        return {
            "statusCode": 400,
            "body": json.dumps({"error": "num1またはnum2が指定されていません"})
        }
    
    result = num1 + num2
    
    return {
        "statusCode": 200,
        "body": json.dumps({"result": result})
    }

このLambda関数は、eventオブジェクトにnum1num2というキーが含まれているかを確認し、含まれていればその合計を返します。もしどちらかが欠けている場合は、エラーメッセージを返す仕組みになっています。

pytestでテストを作成する

次に、このLambda関数が正しく動作するかどうかを、pytestでテストしてみます。まず、pytestの基本的な構造を確認しましょう。テストファイルは、test_lambda.pyという名前で作成します。

import json
import pytest

from my_lambda_function import lambda_handler  # 自作のLambda関数をインポート

def test_lambda_invoke_success():
    # 正常な入力をシミュレート
    event = {"num1": 5, "num2": 10}
    result = lambda_handler(event, None)
    
    # 期待される結果
    expected_body = {"result": 15}
    
    assert result["statusCode"] == 200
    assert json.loads(result["body"]) == expected_body

def test_lambda_invoke_missing_params():
    # num2が欠けているシミュレーション
    event = {"num1": 5}
    result = lambda_handler(event, None)
    
    # エラーメッセージの期待値
    expected_body = {"error": "num1またはnum2が指定されていません"}
    
    assert result["statusCode"] == 400
    assert json.loads(result["body"]) == expected_body

ここで2つのテストを作成しました。1つ目のテストでは、num1num2が正しく与えられた場合の結果をチェックしています。2つ目のテストでは、num2が欠けている場合にエラーメッセージが返されるかを確認しています。

motoでAWS Lambdaをモックする

では、次にmotoを使って、Lambdaの呼び出しをモックしてみましょう。motoはAWSのサービスを模倣するため、実際にAWS環境を用意しなくてもテストができる便利なライブラリです。

まず、motoをインストールします。

pip install moto

motoを使ってLambdaをモックする場合、Lambdaの呼び出しをAWSに送らず、代わりにモックされた環境でテストを行うことができます。これにより、コストをかけずにローカルでテストできるようになります。

では、次に実際のテストコードにmotoを組み込んでみましょう。

import json
import boto3
import pytest
from moto import mock_lambda

# Lambda関数をデプロイするモックを作成
@pytest.fixture
def lambda_client():
    with mock_lambda():
        client = boto3.client("lambda", region_name="us-east-1")
        
        # Lambda関数を作成
        client.create_function(
            FunctionName="MyLambdaFunction",
            Runtime="python3.8",
            Role="arn:aws:iam::123456789012:role/execution_role",
            Handler="my_lambda_function.lambda_handler",
            Code={
                'ZipFile': b"placeholder code",  # 簡易的にZipFileを指定
            },
            Description="This is a test lambda function",
            Timeout=3,
            MemorySize=128
        )
        yield client

# Lambda関数をモックでテスト
def test_invoke_lambda(lambda_client):
    # 正常なリクエストをシミュレーション
    payload = json.dumps({"num1": 3, "num2": 7})
    
    response = lambda_client.invoke(
        FunctionName="MyLambdaFunction",
        Payload=payload
    )
    
    response_payload = json.loads(response['Payload'].read())
    
    # 期待される結果
    expected_result = {"result": 10}
    
    assert response_payload["statusCode"] == 200
    assert json.loads(response_payload["body"]) == expected_result

このコードでは、まずmotoを使ってAWS Lambdaのモック環境を作成し、その中でLambda関数をデプロイします。その後、invokeメソッドを使ってLambda関数を呼び出し、結果をテストしています。

テスト結果

ここまでのコードを実行すると、Lambdaが正しくモックされ、期待通りの動作をするかどうかを確認できます。

$ pytest test_lambda.py

実行結果は以下のようになります。

============================= test session starts ==============================
collected 2 items

test_lambda.py ..                                                       [100%]

============================== 2 passed in 0.45s ===============================

この結果からもわかる通り、無事に2つのテストが成功しました!

まとめ

今回は、pytestmotoを使ってAWS Lambdaのテストを行う方法を学びました。Lambdaをローカル環境でテストするためには、実際にAWS環境を用意しなくても、motoを使ってモックを作成することができるので、とても便利です。特に、開発初期や費用を抑えたいときには、この方法でどんどんテストを追加していくのがおすすめです。

これで、Lambda関数のテストに自信を持って取り組めるようになったと思います。次回は、もう少し進んで、他のAWSサービスとの連携についても触れていきたいと思います。ぜひ次回の記事も楽しみにしていてくださいね!

もし、この記事が役に立ったと思っていただけたら、ぜひツイッターでフォローしてください!お互いに学び合いながら、もっと成長していきましょう。それでは、また次回お会いしましょう!