Back to path
AdvancedTradepost · Project 10 of 12 ~7h· 5 milestones

Build a test suite that catches regressions before customers do

Continues from the last build: Hot reads are cached, abusive clients get 429s, overload sheds instead of melting.

Nine rungs in and it does real things now. It moves money in integer cents, locks rows so stock never oversells, replays idempotent retries, emits events without losing them, and sheds load instead of melting under a spike.

table-driven unit testing with Vitestintegration testing against real Postgres with fastify.injectOpenAPI contract validation with Ajvconcurrency regression testing with Promise.allGitHub Actions CI with Postgres and Redis service containerstest pyramid designidempotency verification under load

What you'll build

By the end, every guarantee built in rungs 1 through 9, money math, order transitions, multi-tenant isolation, idempotent retries, the published contract, and the no-oversell guarantee under concurrency, is enforced by a test that runs on every pull request against real Postgres and Redis. A red test blocks the merge button before a bad change ever reaches production, and the next teammate who touches the order payload finds out in CI, not from a support ticket.

See how we teach, before you sign up

You don't just get code dumped on you. Every starter file and every solution is explained line-by-line, in plain English. Here's one real file from this project:

tests/unit/order-totals.test.tstypescript
import { describe, it, expect } from 'vitest';
import { computeOrderTotals } from '../../src/domain/order-totals';

describe('computeOrderTotals', () => {
  const cases: Array<{ name: string; items: { unitPriceCents: number; quantity: number }[]; expectedCents: number }> = [
    { name: 'single item', items: [{ unitPriceCents: 1999, quantity: 1 }], expectedCents: 1999 },
    // TODO: add a multiple-items case
    // TODO: add a zero-items case
    // TODO: add a large-quantity case that would overflow a float
  ];

  it.each(cases)('$name', ({ items, expectedCents }) => {
    expect(computeOrderTotals(items)).toBe(expectedCents);
  });

  // TODO: add a test that a negative quantity throws before touching the database
});

Reading this file

  • // TODO: add a multiple-items casetable-driven means each new case is one array row, not a copy-pasted test function
  • it.each(cases)('$name'the $name template pulls the case's own name field into the test title so a failure points at the exact row
  • expectedCents: 1999the seed row's shape, name, items, expectedCents, is the shape every row you add must follow

Seed unit test file, one filled row and three TODOs to complete in milestone 1.

That's 1 of 9 explained code blocks in this single project.

The build, milestone by milestone

  1. 1

    Unit test the domain

    6 guided steps

    The domain layer is where money and state live. A bug here corrupts every order that touches it, and a pure-function test catches it in milliseconds without needing a database or a running server. If you only test through HTTP you can't tell whether the route broke or the math broke.

  2. 2

    Integration tests on real Postgres

    6 guided steps

    Unit tests prove the math is right in isolation. Only a real database can prove the query actually filters by merchant, the migration actually applies, and the unique constraint actually fires. Mocking the database here would hide exactly the bugs this milestone exists to catch.

  3. 3

    Contract tests from the spec

    5 guided steps

    Integration tests only prove the code does what the code does. Contract tests prove the code does what openapi.yaml promises the merchants integrating against it. Without this layer, a field rename can pass every other test and still silently break every merchant's integration.

  4. 4

    Concurrency tests as a permanent regression

    6 guided steps

    The lock and the conditional UPDATE from rung 5 only stay correct if something keeps checking them. A refactor months from now could silently swap the conditional UPDATE for a read-then-write and nothing but a concurrency test would notice before a real sale oversold the last five units of stock.

  5. 5

    CI that blocks bad merges

    6 guided steps

    A test suite nobody runs is a test suite that doesn't exist. The four suites you just wrote only prevent the next production incident if a red result physically blocks the merge button, which means running them against the same kind of database and cache the code runs against in production, not a mock.

What's inside when you start

4 starter files, ready to clone
5 guided milestones
5 full reference solutions
9 code blocks explained line-by-line
5 "is it working?" checks
6 interview questions it prepares you for

You'll walk away with

tests/unit covering src/domain (order totals and the order state machine) at 100% statement and branch coverage
tests/integration covering the full order lifecycle, cross-merchant isolation, and idempotent retry against a real Postgres test database
tests/contract validating live responses against openapi.yaml, including one intentional-break test proving the suite catches drift
tests/concurrency locking in the oversell guard and the idempotency guarantee as permanent regression tests
.github/workflows/ci.yml running all four suites against real Postgres and Redis service containers on every pull request
branch protection configured so the CI check is required before a PR can merge

This is portfolio-grade. Build it free.

Sign up to unlock every milestone step-by-step, the code skeletons, full reference solutions, and checkable tasks, with your progress saved as you build.

Start building