unit-test-authoring
Skill1 starsChanged 2 months agoMITView on GitHub
Write unit tests that actually constrain behavior — Jest, Vitest, pytest, Go, JUnit — using red-first discipline, behavior-named cases, and boundary tables. Use when asked to write, add, or improve unit tests, or when implementing a feature test-first.
In this repository34 other files it gives its agents.
- a11y-auditSkill
- api-contract-testingSkill
- autonomous-explorationSkill
- bug-reproSkill
- chaos-resilienceSkill
- ci-wiringSkill
- contract-testing-pactSkill
- coverage-ratchetSkill
- database-testingSkill
- e2e-authoringSkill
- environment-paritySkill
- exploratory-chartersSkill
- false-positive-hunterSkill
- flake-forensicsSkill
- i18n-l10n-testingSkill
- load-and-stressSkill
- mutation-proofSkill
- never-break-prodSkill
- payment-testingSkill
- perf-budgetSkill
- qa-triageSkill
- regression-curationSkill
- release-gateSkill
- responsive-mobile-testingSkill
- risk-mapSkill
- root-cause-protocolSkill
- security-regressionSkill
- smoke-and-sanitySkill
- state-machine-testingSkill
- test-data-managementSkill
- test-strategySkill
- tracking-testingSkill
- transactional-email-testingSkill
- visual-regressionSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 15
If the test was written after the code, you must still see it red: break the production line it covers (comment the branch, invert the …
- Very specific: line 74
Vitest/Jest: prefer toStrictEqual over toEqual.
- Very specific: line 82
Run the suite, paste the output, and report: <n> passed, <n> failed, plus which production line each new test was proven against.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Unit Test Authoring
The red-first law
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST.
NO TEST ENTERS THE SUITE WITHOUT HAVING BEEN SEEN RED.If the test was written after the code, you must still see it red: break the production
line it covers (comment the branch, invert the operator), run it, confirm the failure
message names the real behavior, restore. That is the minimum ritual — the full version
lives in mutation-proof.
A test you never watched fail is a test whose assertion you never verified.
Naming
Name the behavior and the condition, never the function:
- Bad:
test('getTotal'),it('works'),test_calculate_2 - Good:
it('excludes refunded items from the order total') - Good:
def test_rejects_expired_token_with_401()
The name is the spec. If the assertion drifts from the name, false-positive-hunter
flags it as P0 — so keep them in sync or rename.
Boundary table
For every input with an ordering or a size, write the table before the code:
| Class | Cases |
| Numeric | 0, 1, -1, max, max+1, NaN/Infinity, floating-point cents |
| Collection | empty, one, many, duplicate, ordering-dependent |
| String | empty, whitespace-only, unicode/emoji, length limit + 1, injection payload |
| Time | epoch, DST shift, leap day, timezone-crossing, expired-by-1s |
| Optional | null, undefined, missing key, explicit null vs absent |
Parametrize the table; do not copy-paste six near-identical tests.
Structure
it('excludes refunded items from the order total', () => {
// arrange — one intent per test, factories not fixtures
const order = orderFactory({ items: [item({ cents: 1000 }), item({ cents: 500, refunded: true })] })
// act — exactly one call under test
const total = getTotal(order)
// assert — on the value, with a specific expectation
expect(total).toBe(1000)
})Hard rules
- One reason to fail per test. Multiple unrelated assertions = a test whose failure is ambiguous.
- Assert on values, not on truthiness.
expect(x).toBe(1000)— neverexpect(x).toBeTruthy(). - Never assert that a mock was called as the only assertion. That tests your wiring, not behavior.
- Mock at the boundary only (network, clock, filesystem, randomness). Mocking your own module under test makes the test tautological.
- No conditionals or loops around assertions. A test with an
ifcan silently assert nothing. - No shared mutable state between tests. Each test must pass when run alone and in a shuffled order (
--shuffle/-p no:randomlyoff). - Deterministic by construction: fake the clock, seed the RNG, freeze IDs.
Framework notes
- Vitest/Jest: prefer
toStrictEqualovertoEqual;vi.useFakeTimers(); MSW for fetch, never a hand-rolledglobal.fetch = vi.fn()that drifts from the real contract. - pytest:
@pytest.mark.parametrizefor the boundary table; fixtures with explicit scope;freezegunfor time; avoidautousefixtures that hide setup. - Go: table-driven with
t.Run(name, ...),t.Parallel()only when the case owns its state.
Done means
Run the suite, paste the output, and report: <n> passed, <n> failed, plus which production
line each new test was proven against. No output, no claim.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

