user6922072
user6922072

Reputation:

How can I test lambda in local using python?

Is there any way that I can test aws lambda in local? I know there is a package which name is 'localstack' but seems like there is not many people who tried it.

Upvotes: 30

Views: 32393

Answers (5)

Filip Poplewski
Filip Poplewski

Reputation: 198

The best way to test locally more complex AWS lambda functions where development time and local infrastructure is the key. Is usage of their official AWS Lambda docker image.

Simple Dockerfile example from documentation:

FROM public.ecr.aws/lambda/python:3.8

# Copy function code
COPY app.py ${LAMBDA_TASK_ROOT}

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "app.handler" ]

Upvotes: 2

Abnerg
Abnerg

Reputation: 41

[This has changed a bunch since the original question]

Mocking AWS services is tough because they change. Ideally, you use the live service in your dev environment. The problem with live services has been the need to deploy to ..wait.. test every change.

If you only need to develop or debug the lambda function itself, the AWS SAM CLI local invoke is a good choice.

If you also need to invoke other services like S3, Dynamodb, etc, the Stackery CLI is an extension of the AWS SAM CLI built to develop against live cloud resources with the cloudstack's permissions.

The Stackery CLI is language independent and free, but here is a Python serverless quickstart a few other resources.

Upvotes: 2

develoser
develoser

Reputation: 138

I have used Python Lambda Local in pip, https://pypi.python.org/pypi/python-lambda-local

Hope it helps you.

Upvotes: 8

Janis Karklins
Janis Karklins

Reputation: 533

I think that Moto, a library that allows your tests to easily mock out AWS Services, could be very useful.

Imagine you have the following python code that you want to test:

 import boto3

 class MyModel(object):
    def __init__(self, name, value):
        self.name = name
        self.value = value

    def save(self):
        s3 = boto3.client('s3', region_name='us-east-1')
        s3.put_object(Bucket='mybucket', Key=self.name, Body=self.value)

Take a minute to think how you would have tested that in the past.

Now see how you could test it with Moto:

import boto3
from moto import mock_s3
from mymodule import MyModel

@mock_s3
def test_my_model_save():
conn = boto3.resource('s3', region_name='us-east-1')
# We need to create the bucket since this is all in Moto's 'virtual' AWS account
conn.create_bucket(Bucket='mybucket')

model_instance = MyModel('steve', 'is awesome')
model_instance.save()

body = conn.Object('mybucket', 'steve').get()['Body'].read().decode("utf-8")

assert body == b'is awesome'    

With the decorator wrapping the test, all the calls to s3 are automatically mocked out. The mock keeps the state of the buckets and keys.

Upvotes: 8

apoclyps
apoclyps

Reputation: 521

You can run your Lambda functions in the same way you would run any python script e.g.

if __name__ == "__main__":
    event = []
    context = []
    lambda_handler(event, context)

If you use virtual environments, this helps ensure you have all the required dependencies installed for your lambda function alongside the correct python version.

Is there any additional services you need that are present in 'localstack' that you don't have locally?

Upvotes: 31

Related Questions