Skip to content
Quest 10Advanced15 min

Test Your Stack

Infrastructure is code, so you can test it. CDK's assertions module synthesizes your stack in memory and lets you check the template. It runs in milliseconds and never touches AWS.

What you'll learn

  • Template.fromStack(stack) gives you the synthesized template to assert against.
  • Fine-grained assertions (hasResourceProperties, resourceCountIs) check what you care about; snapshot tests catch every change.
  • A test with no assertions can't fail. Test the properties that protect users: encryption, versioning, public access, billing, retention.

Section 01

Fine-grained assertions

Create the stack inside the test, take its template, and assert. hasResourceProperties passes when some resource of that type contains at least the properties you list; extra properties are ignored. resourceCountIs pins how many resources of a type exist.

A test (assumes the full Pokédex stack from the earlier quests)
import { App } from "aws-cdk-lib";
import { Template, Match } from "aws-cdk-lib/assertions";
import { PokedexStack } from "../lib/pokedex-stack";

test("cards are versioned and the table is on demand", () => {
  const stack = new PokedexStack(new App(), "TestStack", { stage: "dev" });
  const template = Template.fromStack(stack);

  template.hasResourceProperties("AWS::S3::Bucket", {
    VersioningConfiguration: { Status: "Enabled" },
  });
  template.hasResourceProperties("AWS::DynamoDB::Table", {
    BillingMode: "PAY_PER_REQUEST",
  });
  template.resourceCountIs("AWS::DynamoDB::Table", 1);
});

Section 02

Matchers

Template values are CloudFormation JSON, so tokens show up as Ref objects. Match helpers let you assert on the shape without writing out every key: Match.objectLike (the default for nested objects), Match.arrayWith, Match.anyValue and Match.absent.

A matcher
template.hasResourceProperties("AWS::Lambda::Function", {
  Environment: { Variables: { TABLE_NAME: Match.anyValue() } },
});

Section 03

What to test

Don't assert every property: the test will break on harmless changes and people will stop trusting it. Assert decisions someone could regress by accident.

  • Safety: public access blocked, encryption on, versioning on, termination protection in prod.
  • Data: removal policy and deletion policy of stateful resources, key schemas.
  • Wiring: the function has the table name; the right function is behind each route.
  • Snapshots: useful for a large construct library, where any change should be a deliberate review.

Practice

Your turn

Write the test. Synthesize the stack into a Template, then assert three things: the bucket has versioning enabled, the table bills PAY_PER_REQUEST, and the stack contains exactly one table. A test with no assertions can never fail.

Two hasResourceProperties assertions and one resourceCountIs.
Tab inserts two spaces. Press Escape, then Tab, to leave the editor. Control or Command plus Enter runs the code.
Simulated — no AWS calls

The simulator runs the constructs this course teaches, plus simple loops and helper methods. Other CDK code may not be recognised.

Check

Check your understanding

Quick Quiz · one question, as many tries as you need.

Which test would have caught a table accidentally switched to provisioned billing?

Choose one answer.