AWS Lambda Testing: AWS Console vs. Local Testing

  • Topics

How Does AWS Lambda Testing Work?

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:

  • Testing functions in the AWS console—this lets you send a sample input to a Lambda function already deployed in the AWS cloud and observe its response.
  • Testing functions locally using AWS SAM—Amazon provides the Serverless Application Model (SAM) CLI, which lets you invoke Lambda functions on your local machine, and even simulate events from other AWS services. This lets you run realistic integration tests on your local machine, before deploying Lambda functions to the cloud.

In this article:

  • Challenges of Testing Serverless Applications
  • Testing Lambda Functions via the AWS Console
  • Private Test Events
  • Shareable Test Events
  • Using Test Events to Invoke Lambda Functions
  • Testing and Debugging AWS Lambda Locally via AWS SAM
  • Invoking Functions Locally
  • Automated Tests
  • Generating Sample Event Payloads

Challenges of Testing Serverless Applications

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.

Testing Lambda Functions via the AWS Console

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.

Private Test Events

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:

  1. In the Lambda console, open the Functions page.
  2. Select the Lambda function you plan to test.
  3. Select the Test tab.

Shareable Test Events

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.

Using Test Events to Invoke Lambda Functions

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:

  1. Go to the Functions section in your Lambda console.
  2. Select the function you plan to test.
  3. Select the Test tab.
  4. Under the Test event section, select Saved event and specify the saved event you plan to use.
  5. Select Test.
  6. Under the Execution result section, you review your test results by expanding Details.

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.

Testing and Debugging Lambda Locally via AWS SAM

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.

Invoking Functions Locally

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"
  }
}

Automated Tests

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:

  1. Start your local Lambda endpoint by executing this command in the directory containing the SAM template:sam local start-lambdaThis command launches a local endpoint simulating AWS Lambda at the address http://127.0.0.1:3001. When you use the AWS CLI (as shown above) or SDK to invoke a local endpoint, it executes the Lambda function specified in your request.
  2. Run the integration test against your local Lambda endpoint. For integration tests, you can invoke a Lambda function on test data using the AWS SDK, then wait for a response and verify that it is as expected.

Generating Sample Event Payloads

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

AWS Lambda Testing with Lumigo

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:

  • Distributed trace for every transaction, which supports both synchronous and asynchronous Lambda invocations. API Gateway, SNS, SQS,
  • EventBridge, Kinesis and DynamoDB streams are all supported
  • The invocation event for every Lambda invocation
  • The request, response and duration for every HTTP(s) request my Lambda function makes to other services, including to other AWS services such as DynamoDB
  • The request, response and duration for some TCP requests, such as those to Redis and MySQL databases
  • Error message and stack trace for erroneous Lambda invocations

With this information, you can easily understand the state of your application and quickly troubleshoot problems. Learn more about Lumigo.