The app ยท 6 min
How it's tested
864 tests, arranged so the logic that matters most is the easiest to test exhaustively.
864 testsBy package
| Package | Tests | Covers |
|---|---|---|
| core | 520 | Normalization, all 56 transitions, every failure reason, copy rules, which changes send an alert |
| dns | 119 | Recorded real responses, zone walking, fixtures, URL signing |
| db | 87 | Constraints, indexes, queries, sessions, rate limits, real concurrency |
| web | 138 | Whole flows through the API, sessions, alerts, setup links, docs matching code |
The layers
Each layer needs more than the one below it. Most tests sit at the bottom, because that's where the decisions are.
Live smokebun run dns:probe, run by handThe real internet
Whole APICreate, fail, fix, verify through handlersPostgres and fixtures
Real databaseConstraints and racesPostgres
Fixture DNSEach failure reason end to endA JSON world
Recorded dataParsing saved real responsesJSON files
Compile timeAn illegal transition doesn't compileThe type checker
Pure logicclassify given hand-built observationsNothing at all
How a test earns trust
- Independent expectations. The state machine test uses a table copied out by hand. If it imported the code's own table, a wrong table would pass.
- Recorded data. The DoH parser is tested against real saved responses, which is how the Google and Cloudflare difference got caught.
- Proving a test can fail. Removing
SKIP LOCKEDmakes its test fail. A test that can't fail proves nothing. - Failing loudly. If Postgres is down, tests fail with instructions. A skipped test looks exactly like a passing one.
- Drift tests. One test fails if the state machine doc stops matching the code, or CI and Docker use different Postgres images.
Testing things that send, without sending
apps/web/lib/server/alerts-and-shares.test.ts builds the API with a container whose mailer pushes each message onto an array, and whose push can be told to answer sent, gone or failed. So a test can verify a domain and then read back exactly one email and one push, or make the mailer fail and check the domain still verified. Sessions are made the same way the app makes them: a real token, with its hash stored by createAccountWithSession.
Predict it first
A test wants an owner and a rival account. Where do they come from now that seeded accounts are gone?
What isn't covered
| Gap | Why |
|---|---|
| Automated live-DNS tests | They depend on the outside world, so joycabinet.com was verified by hand instead. |
| A found record on Vercel | Verified on live DNS from a laptop. On Vercel, a claim has only reached not found so far. |
| Applying at a real provider | No provider has the template. |
| UI component tests | None. The pages were checked by hand in a browser. |
| The shader | No automated tests. It's validated with vgpu check and looked at as PNGs from render-globe.mjs. |
| The service worker | None. public/sw.js is plain JavaScript outside the test setup. |
| Real email and push delivery | The tests use recorders. Nothing has been received from Resend or a push service yet. |
| The rename migration | No automated test. The journal says it was run against a database holding an old row. |