LocalStack LogoLocalStack Icon

Automate Your Serverless Tests with GitHub Actions and LocalStack

Tired of forgetting to run tests before you push? In this tutorial, you'll learn how to automate your serverless integration tests using GitHub Actions and LocalStack. We'll spin up your stack in CI, run real tests against S3, Lambda, SQS, and DynamoDB, and make sure your pipeline catches bugs before they hit production.

Automate Your Serverless Tests with GitHub Actions and LocalStack

You wrote some tests. You ran them locally. You even watched DynamoDB get populated and felt like a responsible developer. If you followed along with the last post, you saw how to verify your S3-to-DynamoDB pipeline using real integration tests, all running on LocalStack without touching the actual cloud. But let’s be honest. Are you really going to run those tests every single time you make a change? Probably not.

That’s why we’re plugging those tests into a continuous integration (CI) pipeline. Now, every time you push code or open a pull request, your LocalStack-powered integration tests will run automatically. No skipped steps. No forgotten test runs. Just fast, consistent feedback. In this post, we’ll set up GitHub Actions to spin up LocalStack, deploy your CDK stack, and run your tests. If anything breaks, you’ll know about it before your coworkers do.

What You’re Setting Up

Here’s what we’ll cover:

  • Creating a workflow file at .github/workflows/test.yml.
  • Using a LocalStack container as a service inside GitHub Actions.
  • Deploying your CDK stack to LocalStack.
  • Running your pytest integration tests just like you do locally.

What You’ll Need

Before we dive in, make sure you have:

  • Integration tests written using pytest and boto3 from the previous post
  • A working requirements.txt that includes your test dependencies.
  • A CDK stack that deploys cleanly with cdklocal.
  • A nice, hot pot of coffee (optional, but helpful).

GitHub Actions Workflow File

Here’s the workflow file we’re using to run tests against LocalStack in CI. It sets up Python and Node, installs your dependencies, spins up LocalStack, deploys your CDK stack, and runs your tests with pytest.

Create a new file at .github/workflows/ci.yml and drop this in:

name: Test on LocalStack
on:
push:
branches: [ main ] # run on pushes to main
pull_request:
branches: [ main ] # run on PRs targeting main
workflow_dispatch: # allow manual runs from the Actions tab
jobs:
localstack-test:
name: Deploy on LocalStack
runs-on: ubuntu-latest
steps:
# 1) Get your repo files onto the runner
- name: Checkout code
uses: actions/checkout@v4
# 2) Python for tests and boto3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
# 3) Node for AWS CDK tooling
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: '20'
# 4) Install your app and test dependencies
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
# 5) Install CDK and CDKLocal, confirm cdklocal is available
- name: Install CDK and CDKLocal
run: |
npm install -g aws-cdk-local aws-cdk
cdklocal --version
# 6) Start LocalStack with Pro features enabled
- name: Start LocalStack
uses: LocalStack/setup-localstack@main
with:
image-tag: 'latest' # pull the latest LocalStack image
install-awslocal: true # also install the awslocal helper
use-pro: true # turn on Pro features
env:
LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }}
# 7) Deploy your CDK app into LocalStack
- name: Deploy CDK stack
run: |
cdklocal bootstrap # one-time infra bootstrap in LocalStack
cdklocal deploy --require-approval never
# 8) Run your tests against the deployed stack
- name: Run tests
env:
AWS_DEFAULT_REGION: us-east-1 # dummy creds are fine with LocalStack
AWS_REGION: us-east-1
AWS_ACCESS_KEY_ID: test
AWS_SECRET_ACCESS_KEY: test
# Optional, helps boto3 find LocalStack if your tests read this env:
# AWS_ENDPOINT_URL: http://localhost:4566
run: |
pip3 install boto3 pytest
pytest --disable-warnings

What’s Happening in This Workflow

Here’s a breakdown of what each step is doing:

  • Step 1: Check out your code so we’re not testing an empty directory.
  • Step 2: Set up Python because pytest and boto3 need it.
  • Step 3: Set up Node because our flavor of AWS CDK is a TypeScript party under the hood.
  • Step 4: Install dependencies so your app and test code can actually run.
  • Step 5: Install CDK tools globally using npm and make sure cdklocal is available.
  • Step 6: Start LocalStack using the official GitHub Action with Pro enabled.
  • Step 7: Deploy your CDK stack using cdklocal, skipping approval prompts.
  • Step 8: Run your tests using pytest, and disable warnings to keep the logs readable.

This workflow mirrors your local dev environment and catches issues as early as possible. If something breaks, the workflow fails, and you’ll know exactly where it fell apart.

Tips and Gotchas

Here are a few extra things worth knowing as you level up your local testing setup:

The setup-localstack action includes built-in health checks, so you don’t need to manually wait for services to be ready. That said, if your stack creates a lot of resources or triggers complex Lambdas, you might want to add a short pause before running tests, just to give everything time to settle.

You’re already using --require-approval never to avoid CDK approval prompts. Good. Keep doing that. If you expand your stack to include other services like SNS, Kinesis, or Secrets Manager, just add them to the SERVICES variable when starting LocalStack.

Try running the workflow locally with act or a test branch before pushing changes to main. CI is not the place to find out your indentation was off by two spaces.

You’re Now Testing Like You Mean It

With this setup, every commit and pull request runs your integration tests against a fully local AWS environment. You catch bugs early, build confidence in your infrastructure, and sleep better knowing that nothing surprising is hiding in staging.

Want to see it all in action?

Watch the companion video where we walk through this CI setup step by step: 👉🏾 Watch the CI walkthrough on YouTube

In the next post, we’ll dig into LocalStack Cloud Pods and show you how to save and restore your infrastructure state. This means faster bootstraps, repeatable environments, and one less reason to say “it worked on my machine.”

Until then, commit often, test early, and break things with confidence.


Kiah Imani
Kiah Imani
DevRel at LocalStack
Kiah Imani is a Senior Dev Advocate at LocalStack, where she turns cloud chaos into clarity. She’s all about making AWS dev feel local, fun, and way less stressful.