Wraps the Serverless Framework (serverless.com) test ecosystem: serverless-offline (local HTTP emulator), serverless-jest-plugin / serverless-mocha-plugin (per-runtime test runners), and the `serverless invoke local` CLI for one-off invocations. Use when testing Lambda functions deployed via the Serverless Framework.
76
95%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
The Serverless Framework (serverless.com/framework/docs) is one of the older deploy-frameworks for Lambda. Its test-friendly ecosystem includes:
npm install -g serverless
npm install --save-dev serverless-offline serverless-jest-plugin jestplugins:
- serverless-offline
- serverless-jest-plugin
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: getserverless invoke local --function hello --data '{"name":"world"}'Output: handler's return value (JSON), plus emulated Lambda log lines.
serverless offline --httpPort 3000Now curl http://localhost:3000/hello exercises the full
Serverless → API Gateway → Lambda route.
Per npmjs.com/package/serverless-jest-plugin:
serverless create test --function hello # Generates test scaffold
serverless invoke test # Runs testsThe scaffold uses Jest under the hood; tests follow standard Jest patterns:
import { hello } from '../handler';
test('returns greeting', async () => {
const event = { queryStringParameters: { name: 'world' } };
const response = await hello(event);
expect(response.statusCode).toBe(200);
expect(JSON.parse(response.body).message).toContain('Hello world');
});// handler.ts
export const hello = async (event: any) => ({
statusCode: 200,
body: JSON.stringify({ message: `Hello ${event.queryStringParameters?.name ?? 'World'}` }),
});
// handler.test.ts
import { hello } from './handler';
test('hello-world', async () => {
const result = await hello({ queryStringParameters: {} });
expect(result.statusCode).toBe(200);
});This skips the Serverless plugin entirely - often the cleanest path.
serverless-offline reads serverless.yml env definitions:
provider:
environment:
DATABASE_URL: ${env:DATABASE_URL}Tests should mirror this via process.env.DATABASE_URL in jest
setup.
npx jest # Direct handler tests
serverless offline # Local HTTP emulator
serverless invoke local --function hello # CLI one-offjobs:
serverless-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
- run: npm ci
- run: npx jestFor deployed-Lambda smoke tests:
- run: serverless deploy --stage staging
- run: npx jest tests/staging-smoke/| Anti-pattern | Why it fails | Fix |
|---|---|---|
Tests use serverless invoke local per test | Subprocess startup cost; slow | Direct handler invocation |
Skip serverless offline for routing tests | API Gateway routing untested | Use serverless offline for HTTP tests |
| Hardcoded env vars in test code | Drift from serverless.yml | Load via dotenv from .env.test |
Mocking event object incompletely | Handler reads event.headers → undefined | Use aws-sam-local-testing generate-event |
| Serverless plugin pinned to old version | Behaviour drift vs prod Lambda runtime | Match Lambda runtime version |
| No deployed smoke tests | Local-pass + prod-fail gap | Always include staging smoke |
| Treating serverless-jest as replacement for direct test | Adds plugin complexity for no gain | Use plain Jest |
cold-start-budget-reference.
Local invocation doesn't simulate Lambda cold start.cold-start-budget-reference,
lambda-timeout-budget-reference.aws-sam-local-testing,
lambda-test-tools-net.serverless-integration-test-builder.