examples/storefront Public
id: testing
type: guide
owner: justin
describes:
- test/helpers/**
reviewed: 2026-10-08
Running and writing tests
npm test # node --test over test/**/*.test.ts
npm run typecheck
The tests need only Node 24. They do not start workerd or wrangler.
How it works
test/helpers/app.ts builds the real fetch handler from createApp with a fresh environment per test:
DBisTestD1(test/helpers/d1.ts), a small D1 stand-in overnode:sqlitewith every file inmigrations/applied in order and foreign keys on. It coversprepare,bind,first,all,runandbatch, and a batch is a transaction, as in D1.IMAGESisTestR2(test/helpers/r2.ts), an in-memory bucket whoseobjectsmap tests can inspect, andIMAGES_URLishttps://images.shop.test.ORDER_EVENTSisTestQueue(test/helpers/queue.ts), which keeps every message insent.- Payments are
FakePayments(test/helpers/payments.ts), which records every charge and fails the next one whenfailNextis set.test/stripe-payments.test.tschecks the real Stripe adapter against a fakefetch, so no test calls Stripe. - The clock is fixed and ids count up (
id-1,id-2), so assertions can name them.
Tests talk HTTP to the handler through call(method, path, body, headers), which returns the status, headers and parsed JSON. addProduct creates a product with the admin token, payments is the fake the app was given and events is its queue.
Writing one
Test behavior through the API rather than the modules, the way a client sees it. When code calls a D1 method the stand-in does not have yet, add it to TestD1 in the same change. A new migration needs nothing: the stand-in applies whatever is in migrations/. See [[0001-d1-for-shop-data]] for why the SQL is shared.