Living Systems Handbook microservices as humans Bipin Singh
Growing a human from DNA

Health check-ups — testing a human

2 min readChapter 15 of 34By Bipin Singh

Before a human starts work — and every time its DNA changes — give it a check-up. Testing a microservice has three layers, from fastest to most realistic.

The testing pyramid, medically

Layer Analogy Tests Speed
Unit tests Testing reflexes The brain's decisions with fake memory and voice Milliseconds
Infrastructure tests Genetic screening The CDK DNA produces the right resources and settings Seconds
Integration / end-to-end tests A full physical The deployed body answers real requests correctly Seconds to minutes

1. Reflexes: unit-testing the brain

Because the brain is pure (see the brain), its tests need no AWS at all — fast and reliable. Test the rules: totals, rejections of unknown items, state transitions.

2. Genetic screening: CDK assertions

CDK's assertions module checks the synthesised template — catching dangerous DNA before deployment.

// test/waiter.infra.test.ts
import { App } from "aws-cdk-lib";
import { Template, Match } from "aws-cdk-lib/assertions";
import { CafeStack } from "../infra/cafe-stack";

const template = Template.fromStack(new CafeStack(new App(), "TestCafe"));

test("the Waiter's memory is on-demand and can be restored", () => {
  template.hasResourceProperties("AWS::DynamoDB::Table", {
    BillingMode: "PAY_PER_REQUEST",
    PointInTimeRecoverySpecification: { PointInTimeRecoveryEnabled: true },
  });
});

test("the Waiter's memory survives stack deletion", () => {
  template.hasResource("AWS::DynamoDB::Table", { DeletionPolicy: "Retain" });
});

test("brain cells run on Node.js 22, ARM, with tracing", () => {
  template.hasResourceProperties("AWS::Lambda::Function", {
    Runtime: "nodejs22.x",
    Architectures: ["arm64"],
    TracingConfig: { Mode: "Active" },
  });
});

test("the Waiter has a pain receptor", () => {
  template.hasResourceProperties("AWS::CloudWatch::Alarm", {
    AlarmDescription: Match.stringLikeRegexp("Waiter is in pain"),
  });
});

Run with npm test. These tests synthesise the stack (bundling functions with esbuild), so they also catch broken imports.

Tip

Add a test whenever a production incident teaches you something: "tables must retain", "functions must have timeouts below 30 s". The DNA learns from its history.

3. A full physical: integration tests

Deploy to a test environment, then exercise the real body:

// test/waiter.e2e.test.ts — runs against a deployed environment
const URL = process.env.FRONT_DOOR_URL!;

test("a customer can place and recall an order", async () => {
  const placed = await fetch(`${URL}/orders`, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ tableNumber: 7, items: [{ menuItemId: "coffee", quantity: 1 }] }),
  });
  expect(placed.status).toBe(201);
  const order = await placed.json();
  expect(order.total).toBe(120);

  const recalled = await fetch(`${URL}/orders/${order.orderId}`);
  expect(recalled.status).toBe(200);
});

test("the skin rejects nonsense", async () => {
  const res = await fetch(`${URL}/orders`, { method: "POST", body: JSON.stringify({ tableNumber: -1, items: [] }) });
  expect(res.status).toBe(400);
});

For event-driven behaviour, a common trick is a test listener: a rule in the test environment that copies events to a queue the test can read, so you can assert "an OrderPlaced event was announced".

Local check-ups

You can run handlers locally (they're just functions), use unit tests with fakes, or invoke deployed functions from your machine. Many teams find a personal sandbox account per developer — deploy in a minute, test against real services — simpler and more faithful than emulating AWS locally.

Key idea

Test the brain with fakes, screen the DNA with assertions, and give the living body a full physical in a real environment. Each layer catches different illnesses.

Bipin Singh
Written by Bipin Singh

Senior Full-Stack Engineer · AI & AWS. I design and build serverless systems on AWS — and love explaining them simply.

Work with me