AWS Lambda
Python
Local Development
Serverless Testing
Lambda Functions

How can I test lambda in local using python?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The fastest way to test an AWS Lambda function locally in Python is to separate business logic from the Lambda handler and run ordinary unit tests against that logic. After that, use a local invocation tool such as AWS SAM when you need to verify the full event shape and runtime behavior. That gives you both fast feedback and realistic integration coverage.

Start with a Thin Handler

A Lambda handler is easier to test when it mostly translates the incoming event into a normal function call. Keep parsing, validation, and response creation close to the handler, and move business rules into plain Python functions.

python
1# lambda_function.py
2
3def build_greeting(name: str) -> str:
4    return f"Hello, {name}!"
5
6
7def lambda_handler(event, context):
8    params = event.get("queryStringParameters") or {}
9    name = params.get("name", "world")
10
11    return {
12        "statusCode": 200,
13        "body": build_greeting(name)
14    }

This structure keeps most of your code independent from the Lambda runtime. That matters because plain Python functions are much easier to test than a full serverless deployment package.

Unit Test the Handler with pytest

You can call the handler directly and pass a small fake context object. For many Lambda functions, this covers the most important logic.

python
1# test_lambda_function.py
2from lambda_function import build_greeting, lambda_handler
3
4
5class DummyContext:
6    function_name = "hello-function"
7
8
9
10def test_build_greeting():
11    assert build_greeting("Mark") == "Hello, Mark!"
12
13
14
15def test_lambda_handler_uses_default_name():
16    result = lambda_handler({}, DummyContext())
17    assert result["statusCode"] == 200
18    assert result["body"] == "Hello, world!"
19
20
21
22def test_lambda_handler_reads_query_parameter():
23    event = {
24        "queryStringParameters": {
25            "name": "Ada"
26        }
27    }
28    result = lambda_handler(event, DummyContext())
29    assert result["body"] == "Hello, Ada!"

Run the tests locally:

bash
pytest -q

This is the best default workflow because it is fast and does not require Docker or a deployed AWS stack.

Test Real Event Shapes with AWS SAM

When you want to verify that your handler works with API Gateway, EventBridge, or S3 event payloads, use AWS SAM. SAM emulates the Lambda runtime more closely than a plain unit test.

A minimal event file for an API Gateway style request might look like this:

json
1{
2  "queryStringParameters": {
3    "name": "Grace"
4  }
5}

Invoke the function locally:

bash
sam local invoke HelloFunction -e events/api-gateway.json

If your Lambda is fronted by an API, you can also run:

bash
sam local start-api

That lets you send normal HTTP requests to a local endpoint while your Python handler executes in a Lambda-like environment.

Mock AWS Services Instead of Calling Real Ones

If your function talks to S3, DynamoDB, or SNS, avoid hitting real AWS services during most local tests. Mock them so your tests stay fast, deterministic, and cheap.

python
1import boto3
2from moto import mock_aws
3
4
5@mock_aws
6def test_s3_bucket_exists():
7    s3 = boto3.client("s3", region_name="us-east-1")
8    s3.create_bucket(Bucket="demo-bucket")
9
10    buckets = s3.list_buckets()["Buckets"]
11    names = [bucket["Name"] for bucket in buckets]
12
13    assert "demo-bucket" in names

This style is useful when your Lambda includes AWS SDK calls but you still want tests that run without network access.

Keep Test Inputs Close to Production Events

Local Lambda tests become much more valuable when the sample events resemble real traffic. Save representative payloads from API Gateway, SQS, or EventBridge and use them in tests and local invocations. That catches mistakes in field names and nested structures early.

Common Pitfalls

  • Writing all business logic directly inside lambda_handler, which makes tests harder to isolate.
  • Relying only on deployed-cloud tests. They are slower and harder to debug than local unit tests.
  • Using fake events that are much simpler than production payloads.
  • Calling real AWS services during unit tests when a mock would be enough.
  • Forgetting to define environment variables locally when the Lambda depends on configuration.

Summary

  • Keep the handler thin and move logic into plain Python functions.
  • Use pytest for fast local unit tests.
  • Use AWS SAM when you need realistic event and runtime behavior.
  • Mock AWS services for deterministic local tests.
  • Reuse production-like sample events so local failures match real issues more closely.

Course illustration
Course illustration

All Rights Reserved.