AWS Lambda is a popular serverless computing service. AWS Lambda eliminates the need to manage servers and infrastructure, but you still need to test your code and see it is free of errors and integrates properly with other components in your event flow.
Serverless debugging can be challenging, because they only run in the cloud, and can be difficult to simulate in an isolated environment. When testing serverless applications, you should focus more on integration tests than unit tests, because functions are almost always triggered by events from external components.
AWS provides two mechanisms that can help you test your Lambda functions are working properly:
In this article
Testing code properly with a managed service requires recreating cloud environments on local machines, but this is not always practical. Another issue with managed services in an event-driven computing architecture is that you need to consider all the external and dependent resources for each service. These include event buses, queues, and database tables.
The result is that you mostly write integration tests rather than unit tests, flipping the conventional testing process. Building large numbers of integration tests might impact the testing speed and maintenance burden.
For synchronous workloads like typical web services, you make requests and assertions on the test response. The thread remains blocked until a response arrives, so there is no need for the test to perform any special function.
On the other hand, if you are working with event-driven architecture, the state changes derive from events flowing between resources. The tests should identify any side effects in the downstream components, but these effects are not always immediately apparent. Tests that can handle asynchronous behavior often tend to be complicated and slow-running.
Related content: Read our guide to serverless testing.
To test a Lambda function in your console, you can invoke the function using a test event. Test events are JSON inputs to a Lambda function.
A private test event is only available to its creator and requires no extra permissions for that creator to use. You can save as many as ten private test events for each function.
To create your private test event:
A shareable test event is an event that other IAM users in your AWS account can access. Users can edit each other’s shareable test events or invoke their own Lambda functions with them.
You can create shareable test events by selecting Shareable under the Event sharing settings.
When running a test event in your console, Lambda will synchronously invoke the function using the test event. The function’s runtime converts the specified JSON document into a portable object, passing it to the code handler method to process.
To test your function:
You can invoke the function without saving the test event by selecting Test before you save it. It will create an unsaved test event that lasts till the end of your session.
Related content: Read our guide to AWS Lambda unit testing.
You can use the SAM Command Line Interface (CLI) to test a serverless application locally, and debug or fix issues before you upload them to AWS.
You can attach the debugger to your Lambda function by locally invoking a function in debug mode, using the SAM CLI. You can then use the debugger to step through your code, view the values of various variables, and fix problems as you would in any other application.
You can invoke a function locally with the sam local invoke CLI command and provide an event file and the function’s logical ID. Alternatively, you can also use the stdin event for this command.
Execute the sam local invoke command in the project directory that contains your Lambda function.
Here is an example of invoking a function locally using an event file:
$ sam local invoke "Ratings" -e event.json
And here is how to invoke a function locally using stdin:
$ echo '{"message": "Hello world" }' | sam local invoke --event—"Ratings"
SAM lets you override environment variables defined in the function template, for testing purposes. To do this, you can use the invoke command with the –env-vars argument and supply a JSON file containing new values for the environment variables. The JSON file should look something like this:
{
"MyFunction1": {
"TABLE_NAME": "localtable",
"BUCKET_NAME": "testBucket"
},
"MyFunction2": {
"TABLE_NAME": "localtable",
"STAGE": "dev"
}
}
In the previous section, we showed how to manually test code using sam local invoke. However, you can also create an automated integration test by running it against a local Lambda function prior to deployment to the cloud.
Use the sam local start-lambda command to launch a local endpoint that simulates an AWS Lambda invocation endpoint. You can then call this endpoint from automated tests. You can write your tests once and run them against your local Lambda functions, or a Lambda function deployed in the cloud, without modification. You can run the same tests on an AWS SAM stack deployed in the CI/CD pipeline.
To run an automated integration test against a local Lambda endpoint:
To create realistic tests of your Lambda functions, you need to simulate event sources that would trigger the function in a real-life scenario. You can create and customize event payloads for many AWS services, such as API Gateway, AWS CloudFormation, and Amazon S3, to facilitate developing and testing Lambda functions locally.
For a complete list of services that can generate sample event payloads, use the following command:
sam local generate-event –help
To see a list of options available for a particular service, use the following command:
sam local generate-event [SERVICE] –help
Regardless of how you test your Lambdas functions, observability plays a critical role in your ability to test effectively. Using an observability solution like Lumigo, which is designed for serverless environments, you have access to wealth of valuable information about your application:
With this information, you can easily understand the state of your application and quickly troubleshoot problems. Learn more about Lumigo.