writing-unit-tests-quick
Skill118 starsChanged 2 months agoMITView on GitHub
Writes a few solid unit tests, using a compact set of rules for structure, assertions, determinism, and edge cases. Use for routine everyday testing of a single function, class, or small module, or for a quick sanity check on tests someone just wrote. For legacy backfills, flaky-suite investigations, deep test-double design, or a full suite review, use the writing-unit-tests skill instead.
We split this skill into the rules it gives an agent
11 rules. About 0 are common, 10 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈10
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 16
Add tests for one function, class, or small module.
- Distinctive: line 25
One reason to fail: If the test name needs "and", split it.
- Distinctive: line 28
Expected values are independent literals: Never recompute them the way the code does, and never import the implementation's own constant - …
- Distinctive: line 29
Assert specific values: Not truthy, not defined. For errors, assert the type and the meaningful part of the message.
- Distinctive: line 30
No logic in the test: No loops or conditionals - use the runner's parameterized/table-driven API so each case reports separately.
- Distinctive: line 33
No real I/O: If proving the behavior needs a database, HTTP call, or browser, say so and route it to integration coverage instead of …
- Distinctive: line 34
Synthetic test data only: No credentials, tokens, or real personal data - a fixture committed once stays in history forever.
- Very specific: line 60
If a test fails intermittently, do not add a retry or raise a timeout.
- Distinctive: line 69
every collaborator stubbed, so the test only proves the stubs were called
- Distinctive: line 87
every test has one reason to fail and a visible Arrange - Act - Assert shape
- Distinctive: line 91
test data is synthetic, and nothing was left skipped without an issue link
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 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
Quick Unit Tests
A compact standard for everyday unit testing: enough to keep tests honest, short enough to read in one pass.
Framework-agnostic - match whatever runner, assertion style, and file layout the project already uses. If none exists, ask which runner to target before writing anything.
When to Use
- Add tests for one function, class, or small module.
- Sanity-check a handful of tests someone just wrote.
- Cover a bug fix or a small new branch.
Escalate to writing-unit-tests when the job is a legacy backfill, a flaky or slow suite, a full-suite review, or heavy test-double design. Use test-driven-development when the tests should come before the code.
The Rules
- Test behavior, not implementation. Assert what the public interface returns, throws, or emits. Never touch private state.
- One reason to fail. If the test name needs "and", split it.
- Name the behavior and the condition.
returns zero when the cart is empty- the CI log alone should say what broke. - Arrange - Act - Assert, visibly separated, with exactly one call to the unit under test.
- Expected values are independent literals. Never recompute them the way the code does, and never import the implementation's own constant - that test can only agree with the code.
- Assert specific values. Not truthy, not defined. For errors, assert the type and the meaningful part of the message.
- No logic in the test. No loops or conditionals - use the runner's parameterized/table-driven API so each case reports separately.
- Control nondeterminism. Inject or freeze time, randomness, and IDs; use fake timers instead of real delays; await every promise and assert rejections directly.
- Mock only what you do not own. Network, storage, clock. Never stub your own modules - that freezes the design and breaks on every refactor.
- No real I/O. If proving the behavior needs a database, HTTP call, or browser, say so and route it to integration coverage instead of mocking around it.
- Synthetic test data only. No credentials, tokens, or real personal data - a fixture committed once stays in history forever.
- Leave nothing skipped silently. A
skiporonlycarries an issue link and an owner, or it does not land. - Do not reshape the code to suit the test. Hard-to-test code is a design finding to raise, not something to restructure inside a test-adding change.
Cases to Cover
For each unit, walk this list and keep what applies:
- happy path - typical input
- input classes - one representative per meaningfully different group
- boundaries - empty, zero, one, min, max, off-by-one, just outside the range
- invalid input - wrong type, malformed value, missing required field
- error paths - thrown errors, rejected promises, failure return values
- state or sequence - behavior that depends on what happened before
Skip trivial getters, framework wiring, and third-party library behavior. A test with nothing to prove still breaks on refactors.
Before You Finish
Two checks, both quick, and both run rather than imagined:
- Mutation check - break the covered behavior on purpose, run the test, see it fail, restore the code, see it pass. A test written after the code has never been seen failing; this is the only thing that proves it can.
- Refactor check - rename internals and restructure without changing behavior. Does the test still pass? If not, it is coupled to implementation.
Then run the full suite, not just the new tests, and quote the real result.
If a test fails intermittently, do not add a retry or raise a timeout. Reproduce it first - repeat runs, isolation, random order, parallel on and off - then fix the cause. writing-unit-tests carries the triage procedure.
Common Failure Modes
- expected value recomputed the same way the implementation computes it
- one test asserting five unrelated things, so a failure says nothing
toBeTruthy()where a real value belongs- a
try/catcharound the act step that passes when nothing throws - real clock, real
sleep, or real network inside a unit test - every collaborator stubbed, so the test only proves the stubs were called
- a mutation check assumed rather than executed, so nobody knows the test can fail
- an expected value quietly changed to match whatever the code returned, turning a spec into a characterization test
- a flake contained with a retry or a longer timeout instead of diagnosed
- a skipped test with no issue link, quietly removing coverage
- real credentials or personal data in a fixture
- tests added to move a coverage number
Related Skills
writing-unit-tests- the full standard: legacy backfills, flaky suites, test-double design, suite reviewunslop-tests- the named-tell audit for tests that already existtest-driven-development-quick- when the tests should drive the implementation, in the same compact formtest-driven-development- the full loop, for multi-unit features and legacy codedesigning-test-data- when the inputs and boundary values need deliberate design first
Definition of Done
- every test has one reason to fail and a visible Arrange - Act - Assert shape
- expected values are independent literals
- nothing depends on real time, randomness, I/O, or another test's state
- boundaries and error paths are covered, not just the happy path
- test data is synthetic, and nothing was left skipped without an issue link
- both the mutation and refactor checks were actually run, and the full suite is green with its result quoted
In this repository51 other files it gives its agents.
- analyzing-quality-metricsSkill
- analyzing-regression-scopeSkill
- api-playwright-test-developerSkill
- assessing-comprehension-debtSkill
- assessing-release-readinessSkill
- attesting-manual-verificationSkill
- auditing-accessibilitySkill
- code-review-advancedSkill
- code-reviewSkill
- communicating-quality-findingsSkill
- creating-custom-agentsSkill
- creating-hooksSkill
- creating-instructionsSkill
- creating-orchestration-packsSkill
- creating-pluginsSkill
- creating-promptsSkill
- creating-skillsSkill
- deriving-a-quality-contractSkill
- designing-functional-testsSkill
- designing-test-dataSkill
- documenting-test-suitesSkill
- generating-quality-gate-workflowsSkill
- governing-quality-waiversSkill
- handling-sensitive-test-dataSkill
- migrating-tests-to-playwrightSkill
- mocking-network-and-timeSkill
- planning-exploratory-testingSkill
- prd-generatorSkill
- recording-change-intentSkill
- reporting-bugsSkill
- requirements-test-coverage-mapperSkill
- reviewing-ai-output-groundednessSkill
- running-visual-regression-testsSkill
- scoping-change-relevanceSkill
- static-code-analysis-typescriptSkill
- tech-debt-analysisSkill
- test-driven-development-quickSkill
- test-driven-developmentSkill
- testing-agent-skillsSkill
- testing-api-contractsSkill
- testing-application-securitySkill
- testing-llm-featuresSkill
- testing-llm-guardrailsSkill
- testing-performance-and-loadSkill
- tracing-requirements-to-codeSkill
- tracking-quality-trendsSkill
- unslop-answersSkill
- unslop-testsSkill
- verifying-acceptance-criteriaSkill
- verifying-change-coverageSkill
- writing-unit-testsSkill
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.

