If you’re just starting out working with AWS Lambda there are a LOT of things for you to understand. And of course, one of those areas is going to be: testing.
How to test AWS Lambda? AWS Lambda can be tested manually using the AWS console with test events. In addition to manual testing, AWS Lambda can also be tested through local replication with tools like as docker-lambda. Or finally, testing AWS Lambda can be done using an automated (CI) pipeline for running unit, component and integration tests.
There’s a few different ways you can go about testing AWS Lambda, today we’ll run through these different options, and I’ll let you know what has worked best in my experience and where I’d suggest you spend your energy on.
What Is a Test Event in AWS Lambda?
One of the first topics that you’ll run into when looking into how to test AWS Lambda is: events. You’ll hear people talk about lambda as being “event-driven”, but what do they mean? And what does it mean for us and our testing?
An event in AWS Lambda is the object which invokes your AWS Lambda. The event can come from a long list of different sources within AWS, such as DynamoDB, Kinesis, SQS, Load Balancers, and more.
All of these different sources create different event object structures, so dependent on what service you’re integrating with you’ll need to need to an example of what the event looks like that you’ll be working with (we discuss in the next section how to find and use test events relevant for you).
The AWS Lambda event will contain information about the source that invoked it, and it will pass any arguments to your AWS Lambda. If you’re integrating with API Gateway, for instance, you’ll get the things you expect, such as the URL, the URL parameters, the body of the request, the headers and so on.
At this point I can imagine you’re keen to see what your test event will look like. One of the easiest ways to explore the test events is through experimenting within the console with test events, let’s look at how to do that now.
How To Trigger a Test Event in The AWS Lambda Console
The easiest way to view these events in AWS Lambda is by using the console. To trigger a test event, start by logging into your AWS account, and opening up your AWS Lambda function console.
You’ll see in the top right hand of the screen that there’s a drop down titled: “select a test event”.
Since you probably haven’t done this before, go ahead and create a new test event. When you click on create new test event, you’re given a drop down of all the different AWS services which can integrate with AWS Lambda.
At this point it can be interesting to click through these different sources and take a look at the different test events that can be passed in, and what type of data you’ll get alongside your test event.
If you don’t know which AWS service you’ll be integrating with just yet, go ahead and pick the “Hello World” event, which is just a generic event, not associated with any service, which should be enough to get you started.
Now give your new test event a name (any name will work) and hit create.
You have now stored your test event for later. You should see at the top right hand corner that your test event is loaded into the drop down. Go ahead and hit test and this will invoke the AWS Lambda using your created test event.
If you’ve got logs enabled, you’ll be able to view the invocation log output.
If you want to get a real test event add a log line entry at the start of your AWS Lambda which logs the invocation event. The event will be passed through into CloudWatch logs and you can pull out that event if you want to use real data.
Now, let’s move onto a different, but similar topic when it comes to testing AWS Lambda, and that’s how to setup your AWS Lambda function locally.
How to Run an AWS Lambda Function Locally?
Running an application locally to test the code as you write it is a common workflow most software engineers are familiar with. But when it comes to AWS Lambda, setting up local invocation can get a little tricky.
One big reason that testing AWS Lambda locally can get difficult is because of the tight integrations that AWS Lambda has with many other AWS services. Replicating locally different AWS services can be difficult.
Depending on what tools you’re using currently, there are a few different options which I wanted to walk you through which might help you out when it comes to setting up local replication.
Docker Lambda — Docker Lambda is a tool which tries to replicate the AWS Lambda environment as closely as possible, but within a Docker container. Docker Lambda has support for most of the AWS Lambda run times.
Serverless Offline — Serverless Offline is a Serverless Framework plugin for emulating API gateway requests locally. And Serverless Framework itself also has some utilities which can be useful for running functions locally.
AWS SAM — If you’re using AWS SAM for your AWS Lambda, there are some different commands from AWS SAM which you can use to test your AWS Lambda locally either by directly invoking or by running your AWS Lambda function as a web server.
These AWS Lambda framework tools are cool and can be fun to play with, but don’t forget that an AWS Lambda is just a function, and setting up local invocation can be done with your own custom scripts.
The simplest way to setup local invocation yourself is to take an existing AWS Lambda handler, import it into a script and then execute it with the expected values, such as the AWS Lambda event object and the context object.
Alternatively, you can also wrap your AWS Lambda handler in a web server so that you invoke it the handler using a URL. You can even set your web server to pass the body of a request as the event so you can test different inputs easily.
Everything we’ve talked about so far covers only how to test AWS Lambda in a manual hands-on type of way. But, as software engineers, setting up automation for tasks where possible is what we prefer. Which raises the question: How can we test our AWS Lambda function in an automated fashion?
How To Automate AWS Lambda Testing
Testing AWS Lambda functions manually can be a pain, so having things automated really can help speed up development.
There’s a few things you’ll need to have setup in order to test your AWS Lambda function in an automated way, these are: setting up an automation (CI) pipeline, unit testing, component testing, and integration testing.
Each of these topics of setting up automation for AWS Lambda can get pretty complicated, so let’s break them down and go through them one-by-one.
Setup An Automation (CI) Pipeline For AWS Lambda
The first thing you’ll need to setup to have automated testing is an automated pipeline to actually run your tests. If you’ve don’t have any automation pipeline tools setup I highly recommend Github Actions.
Why Github Actions? Because it’s free (up to a point), and most of you reading will already be hosting your code in Github, so it’s likely that you won’t need any additional accounts or setup to get started.
If Github Actions doesn’t work for you, for whatever reason, I’d suggest also looking into CodePipeline. CodePipeline is an AWS product, so it might fit your needs better than Github Actions.
Once you’ve got an automation pipeline setup, you can start to add steps into your pipeline that can be executed to test your AWS Lambda function. It’s typical to run these tests on each push to your code repository.
When you have your automation setup, you’ll be ready to add some test steps, let’s start by looking at the first testing step you’ll want to setup, unit testing.
Setup Unit Tests For AWS Lambda
Unit tests is the testing of the smallest possible parts of your code, in a quick, repeatable way.
With unit tests you’re going to mock out the different calls to other services, so if you make an HTTP request, that should be mocked out. If you use the AWS SDK, that should also be mocked out.
The reason that we mock out calls in unit tests is so that they run quickly. We acknowledge that sometimes our unit tests aren’t perfect replications of the real world, but they can come close, and they’re a good first step for testing.
AWS Lambda is not opinionated at all about how you setup your own function, so it can feel like you’re on your own when it comes to structuring your AWS Lambda function so that it can be unit tested easily.
If you already have your handler function written, start by breaking out small parts of the handler into small functions which can be exported and tested. The key here is to keep these functions simple.
Once you’ve got some basic unit tests in place, it’s now time to focus on the next step, component testing.
Setup Component Tests For AWS Lambda
Component tests, in my opinion, are one of the most under-utilised, not-often-discussed strategy for testing AWS Lambda functions.
Component tests are quite like unit tests, they use the same unit test framework, and you’ll still mock out calls to different services, but rather than testing individual functions, you’ll test the entirety of the AWS Lambda handler.
For instance, if you have an AWS Lambda which is an API, such as a user API, you would mock out calls to the database which fetch user information and then invoke your handler with a given user and test the response value.
At this point, I should warn you: component tests are a dance with the devil. If you’re not careful, you’ll end up duplicating a lot of your unit testing code into your component tests and you could end up with lots of extra code to maintain.
If you setup component tests thoroughly they should give you confidence your AWS Lambda function works whilst being fast and repeatable.
We’re now left with the last step, which is integration tests.
Setup Integration Tests With AWS Lambda
Integration testing is different to unit and component testing because integration tests can look very different depending on your setup and architecture. Put simply: there’s no one-size-fits-all method for integration testing.
But, I don’t want you to leave today without having some tactics that you can experiment with, so let’s take an example of a common use case such as setting up an HTTP API and see how we would integration test it.
To integration test an AWS Lambda using an HTTP API, the best thing you can do is deploy the AWS Lambda function into your AWS account, make HTTP requests to the service and then test the responses.
You could use a test framework for your integration tests, or you could use something as simple as a bash script to CURL your URL, and check if the response is expected. Don’t overthink testing, it can be simple if you need.
But since I mentioned that testing setups can vary based on architecture, let’s take another example and see how we would about integration testing it, and see how the two techniques might differ.
Let’s say that our AWS Lambda is triggered by an S3 file upload, and then it records an item in a database. How would we go about integration testing this?
If this was architecture I was working with, I’d compose a test which uses the AWS SDK, or CLI to upload a file into S3, to trigger the AWS Lambda, and then follow up by querying the database to ensure the correct entry was written.
Sometimes there’s no simple way to write integration tests, so you’ll going to to have to create a test using the AWS CLI, or the SDK. The main thing is to try to keep the complexity in the tests low, and keep the tests deterministic, i.e given the same input they return the same output, repeatedly.
With integration tests your focus should be on covering only a few of the main paths through your AWS Lambda function. Leave all the finer details of testing to your unit and component tests.
If you put in place all three of these testing layers: unit, component and integration testing, you’re going to have a strong automated testing strategy for your AWS Lambda function.
Fully Tested AWS Lambda Functions
And on that note, that rounds off everything we were going to cover today. I’m hoping this pointed you in the right direction of where to look, and how to start thinking about testing AWS Lambda functions.
If you’re interested in AWS Lambda functions, check out: Serverless: An Ultimate Guide, and if you’re looking for books or courses on cloud engineering, check out: My (Highly!) Recommended Books & Courses To Learn Cloud Engineering.
Speak soon, Cloud Engineering friend.