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.
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:
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 functionit.each(cases)('$name'the $name template pulls the case's own name field into the test title so a failure points at the exact rowexpectedCents: 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
Unit test the domain
6 guided stepsThe 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
Integration tests on real Postgres
6 guided stepsUnit 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
Contract tests from the spec
5 guided stepsIntegration 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
Concurrency tests as a permanent regression
6 guided stepsThe 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
CI that blocks bad merges
6 guided stepsA 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
You'll walk away with
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