subroutine — testing discipline
Apply this to TypeScript tests. The nearest AGENTS.md decides the runner,
allowed layers, and React test policy.
Prove behavior
- For a bug, write the smallest regression test and see it fail before the fix.
Name the behavior, not the implementation.
- Assert public outputs, effects, events, or typed errors. Avoid private tests,
incidental call counts, and broad snapshots.
- Cover success, every expected
Result variant introduced by the change, and
unexpected rejection when propagation is part of the contract.
test("returns CONFLICT for a duplicate reference", async () => {
store.insert.mockRejectedValue(uniqueViolation);
await expect(createOrder({ input, store })).resolves.toEqual(
err({ code: "CONFLICT", reason: "duplicate-reference" }),
);
});
test("preserves an unexpected database outage", async () => {
store.insert.mockRejectedValue(outage);
await expect(createOrder({ input, store })).rejects.toBe(outage);
});
Keep tests trustworthy
- Inject time, IDs, randomness, and clients only when behavior depends on them.
Fake an owned port; never mock a query builder or private call chain.
- Keep fixtures minimal and explicit. A fixture default must not hide the field
the test is meant to exercise.
- Unit-test deterministic logic; integration-test real serialization, database,
or transport boundaries. Do not simulate integration with a forest of mocks.
- Never add
.test.tsx, DOM tooling, or component snapshots when repository
policy tests only extracted pure UI logic.
1---2name: testing-discipline3description: Testing discipline for TypeScript test files — reproduce regressions first, test observable behavior and typed failures, keep doubles at owned boundaries, and preserve unexpected rejections.4---56# subroutine — testing discipline78Apply this to TypeScript tests. The nearest `AGENTS.md` decides the runner,9allowed layers, and React test policy.1011## Prove behavior1213- For a bug, write the smallest regression test and see it fail before the fix.14 Name the behavior, not the implementation.15- Assert public outputs, effects, events, or typed errors. Avoid private tests,16 incidental call counts, and broad snapshots.17- Cover success, every expected `Result` variant introduced by the change, and18 unexpected rejection when propagation is part of the contract.1920```ts21test("returns CONFLICT for a duplicate reference", async () => {22 store.insert.mockRejectedValue(uniqueViolation);23 await expect(createOrder({ input, store })).resolves.toEqual(24 err({ code: "CONFLICT", reason: "duplicate-reference" }),25 );26});2728test("preserves an unexpected database outage", async () => {29 store.insert.mockRejectedValue(outage);30 await expect(createOrder({ input, store })).rejects.toBe(outage);31});32```3334## Keep tests trustworthy3536- Inject time, IDs, randomness, and clients only when behavior depends on them.37 Fake an owned port; never mock a query builder or private call chain.38- Keep fixtures minimal and explicit. A fixture default must not hide the field39 the test is meant to exercise.40- Unit-test deterministic logic; integration-test real serialization, database,41 or transport boundaries. Do not simulate integration with a forest of mocks.42- Never add `.test.tsx`, DOM tooling, or component snapshots when repository43 policy tests only extracted pure UI logic.