26

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.

  • 1
    [Atlassian `localstack`](https://github.com/atlassian/localstack) exists, but it's probably overkill to test just Lambda functions. It must be good if you have to test more AWS stuff in concert. – 9000 Mar 30 '17 at 15:27

4 Answers4

29

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?

eliasah
  • 39,588
  • 11
  • 124
  • 154
apoclyps
  • 501
  • 5
  • 9
  • 1
    Can you have a `lambda_handler` and `cli_handler` function so the script works both on the command line with passed in click arguments and as a lambda function? As the example will cause the lambda function to run twice. – mRyan Aug 12 '20 at 11:27
  • How do you post data to `lambda_handler` though? A minimal but complete example would be great to see. – duhaime Oct 28 '22 at 11:39
  • 1
    As it's been 5 years since this original answer, there have been significant changes in the ecosystem. The above solution is the most basic/rudimentary way to invoke a python function by running a file. For making a POST request to an API and calling a lambda, you may want to explore the AWS Serverless Application Model (AWS SAM) as this has some tooling in place to help with testing this usecase: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html – apoclyps Oct 29 '22 at 12:06
8

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.

mabe02
  • 2,676
  • 2
  • 20
  • 35
Janis Karklins
  • 503
  • 1
  • 7
  • 19
8

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

Hope it helps you.

develoser
  • 128
  • 2
  • 5
2

[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.

Abnerg
  • 41
  • 4