Harness testing
Skills we wrote for ourselves while building Looties. Figured others could use them too.
npx -y skills add looties-io/looties-skills --skill harness-testingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when writing, designing, or strengthening harness tests — tests that boot a larger unit of a system (an HTTP handler, a job, a UI flow) into a realistic but controlled environment (fake requests, mocked services/APIs, controlled env vars, an in-memory/seeded database, fake timers) and assert end-to-end behavior. Use when asked to "test the whole handler", "integration test without a real DB/network", "mock the services and run the real code path", "add a test harness", or to improve reliability of code that only misbehaves when wired to its dependencies. Framework-agnostic; includes notes for TypeScript/Deno/Node, Python, and Go.
SKILL.md
7.0 KB, as published. Nobody here has run it
Harness Testing
A harness test runs your real code inside a wrapper that simulates the runtime just enough to verify behavior: fake inputs, mocked services, controlled env, a seeded in-memory database, fake timers, and setup/teardown. Instead of testing one function in isolation, you plug a larger unit — a request handler, a worker, a screen-level flow — into a realistic-but-controlled environment and assert what it actually does.
Use it for behavior that only appears when code is wired up: auth and status codes, payload assembly, branching, persistence, retries, error handling. Keep pure-logic unit tests for isolated helpers.
The one rule: non-invasive
Never change production code to make it testable. No dependency-injection refactors, no "export the handler just for tests", no test-only flags in shipped code. A harness that demands production changes isn't riskless and won't be adopted for the code that matters most. Intercept a seam instead (below). If you genuinely cannot reach a seam without touching production, that's a design finding to raise — not a reason to weaken the rule.
Step 1 — Find the one seam
A harness is only as simple as its interception point. Find the single boundary that every external dependency crosses, and mock there — not once per dependency.
- Outbound network is usually the seam: most SDKs (DB clients, payment, email, storage) ultimately
call the platform's HTTP primitive. Intercept that and you mock them all with one mechanism.
- TypeScript/Deno/Node: replace
globalThis.fetch(verify your SDKs use it — many do in modern runtimes), or usenock/msw. - Python:
responses/respx, or monkeypatchrequests/httpx. - Go: inject an
http.RoundTripper/httptest.Server.
- TypeScript/Deno/Node: replace
- The entrypoint is the other seam: capture the handler the framework would serve, and call it
with a fake request — without starting a server. (E.g. intercept the serve call to grab the handler
closure; build a fake
Request; assert on the returnedResponse.) - The clock: swap in fake timers so time-dependent logic (timeouts, retries, TTLs) is deterministic.
One seam = one mental model. Resist per-dependency mocks; they drift and multiply.
Step 2 — Build the harness toolkit
Small, composable, single-purpose pieces:
loadUnit(...)— boot the real handler/component/job (intercepting the entrypoint, not editing it).router(routes)— matchmethod + url → canned response, and record every call for assertions.seededStore(data)— translate an in-memory dataset into the responses the data layer expects; record writes so tests can assert persistence.withEnv(vars)— snapshot, set, and restore environment variables.makeRequest(...)— build fake inbound requests.createHarness({...})— wire the above + fake timers, exposerequest()and the recorders, and register oneteardown().
Step 3 — Write the test
Arrange (env + seed + routes) → boot the real unit → act (one fake request / one render) → assert on
the real output and the recorded outbound calls → teardown() in finally.
// Illustrative (TypeScript). Adapt the seam to your stack.
const h = await createHarness({
unit: './handlers/checkout', // booted, not modified
env: { SERVICE_KEY: 'test', API_BASE: 'https://api.test' },
db: { tables: { orders: [], items: [{ id: 'i1', price: 100 }] } },
routes: [{ method: 'POST', url: 'api.payments.test', respond: () => json({ id: 'pay_1' }) }],
});
try {
const res = await h.request({ method: 'POST', url: '/checkout', body: { itemId: 'i1' } });
expect(res.status).toBe(200);
expect(h.db.tables.orders).toHaveLength(1); // persistence
expect(h.calls.some((c) => c.url.includes('payments'))).toBe(true); // outbound
} finally {
h.teardown();
}
Principles (the difference between a harness that helps and one that lies)
- Boot the real thing. Mock dependencies, never the unit under test. The value is exercising real code against fakes — not re-implementing its logic in the test.
- Loud unmatched, never silent. An unhandled dependency call must throw with a clear message,
not return
undefinedor hang. Silent gaps produce green tests that assert nothing. - Seed lazily, tear down completely. Read seeded data at execution time so tests arrange before
acting. One
teardown()reverts every global you touched (network, entrypoint, env, timers) in reverse order; call it infinally. Cross-test leakage is the #1 harness failure mode. - Pin actual behavior, not assumed behavior. The first boot will surprise you — that's the point. Assert what the code does (the real status code, the real error text), record the surprise, and don't quietly "fix" production to match your assumption.
- Keep the fake minimal; extend on demand. Emulate only the verbs the unit uses. A smaller fake is easier to trust. Add a verb deliberately when a test needs it — never loosen matching to pass.
- Own only what you can clean up. Real clients start background work (refresh timers, pools) the unit never disposes because the runtime tears it down. Disable leak/resource sanitizers for harness tests specifically rather than editing production to satisfy a detector.
- Fast, separate, gated. No real I/O. Name harness tests distinctly (e.g.
*.harness.test.*) so the unit suite stays quick, and fold them into the one verification command the whole team and every agent runs — so they're backpressure that rejects regressions, with CI as the mechanical ratchet.
Anti-patterns
- A test that passes whether or not the code under test runs (over-mocked, asserts nothing real).
- Editing production code "just a little" for testability — start over from a seam.
- A bespoke mock per dependency — collapse to one seam.
- Matching
*/ catch-all routes everywhere — fine for a "did it reach real work" smoke, but specific routes are what let you assert the right calls happened.
Background reading
Anthropic — Harness Design for Long-Running Apps; Effective Harnesses for Long-Running Agents.
OpenAI — Harness Engineering. Geoffrey Huntley — Ralph Wiggum as a Software Engineer.
celesteanders/harness — docs/best-practices.md.
See references/checklist.md for a copy-pasteable pre-flight checklist.