unit-testing
Skill8 starsChanged 9 days agoMITView on GitHub
Writes and updates unit tests for new or changed code in the project's existing framework and style, covering happy, error and boundary paths, then runs them with coverage and fixes failures. Use when implementing a feature or bug fix that needs tests, when asked to add or update unit tests or improve coverage for specific code, or when unit tests fail after a change. Not for choosing between test levels or fixing flaky tests (use test-strategy).
20 other projects use a version of this.
Adopted by
Most recently taken up by
- petrkindlmann/qa-skillstheir own version, first seen Oct 25, 2026
- lggarrison/agent-skillstheir own version, first seen Oct 25, 2026
- r-portas/skillstheir own version, first seen Oct 20, 2026
- prinx/agentstheir own version, first seen Oct 20, 2026
- sb-dev/narrative-production-skillstheir own version, first seen Oct 20, 2026
- pulsejet/memoriestheir own version, first seen Oct 17, 2026
Used with
Projects with it also use contract-testing, e2e-testing and 1 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
petrkindlmannSkillcontract-testing
Implement consumer-driven contract testing with Pact-JS (v16). Covers consumer test writing, broker-driven provider verification, Pact Broker setup, can-i-deploy as a deployment gate, webhook-triggered verification, pending pacts, and schema-first vs consumer-first approaches (OpenAPI/Ajv, Schemathesis). Use when: "contract test," "Pact," "consumer-driven," "API contract," "provider verification," "can-i-deploy." Not for: stubbing or mocking a dependency to isolate a test — use service-virtualization; general REST/GraphQL endpoint assertions against your own API — use api-testing. Related: api-testing, service-virtualization, ci-cd-integration, test-environments.
Also in 3 projects that use this
etewiahSkille2e-testing
Playwright E2E testing and Lighthouse performance auditing. Use when setting up E2E tests, running Playwright tests, performing Lighthouse audits, or debugging E2E test failures.
Also in 4 projects that use this
Microsoft AzureSkillrelease-readiness
Complete ODIN release documentation and validation checks before declaring user-visible work complete, preparing a release, or opening the Release-to-main pull request.
Also in 3 projects that use this
Other versions20 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 20
- pulsejet/memories★ 3.9ksame name
- lichtblick-suite/lichtblick★ 1.2ksame name
- javierbrea/eslint-plugin-boundaries★ 1ksame name
- petrkindlmann/qa-skills★ 209same name
- kid-sid/claude-spellbook★ 190same name
- dprakash2101/dotnet-production-agent-skills★ 4same name
- ffsshhttiikk/opencode-agents-skills★ 2same name
- sb-dev/narrative-production-skills★ 2same name
- axross/skills★ 1same name
- iamcaominhtien/kanban-board-mcp★ 1same name
10 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository60 other files it gives its agents.
- api-designSkill
- auth-implementationSkill
- background-jobsSkill
- building-agentsSkill
- caching-strategiesSkill
- ci-cd-pipelinesSkill
- cloud-cost-optimizationSkill
- codebase-onboardingSkill
- code-review-changesSkill
- concurrency-patternsSkill
- database-migrationsSkill
- database-schema-designSkill
- database-testingSkill
- data-pipelinesSkill
- data-privacy-retentionSkill
- dependency-upgradesSkill
- design-docsSkill
- design-systemsSkill
- dockerfilesSkill
- domain-driven-designSkill
- event-driven-architectureSkill
- file-storage-uploadsSkill
- frontend-securitySkill
- git-workflowSkill
- graphql-apisSkill
- grpc-servicesSkill
- incident-responseSkill
- infrastructure-as-codeSkill
- internationalizationSkill
- kubernetes-deploymentsSkill
- large-scale-migrationsSkill
- legacy-refactoringSkill
- llm-evalsSkill
- llm-integrationSkill
- mcp-serversSkill
- micro-frontendsSkill
- ml-experimentsSkill
- monorepo-managementSkill
- nosql-designSkill
- observabilitySkill
- orm-patternsSkill
- performance-profilingSkill
- postgres-operationsSkill
- rag-systemsSkill
- react-patternsSkill
- realtime-apisSkill
- resilience-patternsSkill
- root-cause-debuggingSkill
- search-integrationSkill
- security-auditSkill
- seo-and-ssrSkill
- sql-optimizationSkill
- system-designSkill
- test-strategySkill
- threat-modelingSkill
- typescript-patternsSkill
- verify-before-doneSkill
- web-accessibilitySkill
- web-performanceSkill
- writing-skillsSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
13 rules. 0 are common, 12 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 17 edited versions we read keep these.
12
Distinctive
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 9
Every behavior you added or changed gets a unit test that would fail if that behavior broke.
- Distinctive: line 17
Not for: deciding unit vs integration vs end-to-end, test doubles across a whole system, or flaky tests.
- Distinctive: line 21
Detect the framework and conventions: Look for config and existing tests:
- Distinctive: line 39
Hand off to verification: Run the full project checks with the verify-before-done skill before reporting.
- Very specific: line 54
If the project already has a coverage script (for example npm run test:coverage), use it instead.
- Distinctive: line 58
Use the report to find untested behavior: an error branch with no test, a boundary never hit.
- Distinctive: line 59
Never write a test only to execute lines.
- Distinctive: line 60
Don't lower a project's coverage threshold to make CI pass.
- Distinctive: line 90
When a unit test fails after a change, decide which side is wrong before touching anything:
- Distinctive: line 100
Never delete, skip or loosen a failing test just to get green.
- Distinctive: line 104
Testing private methods directly: Test through the public interface.
- Distinctive: line 111
Tests written after the fact that only pass: never seen failing, so never proven.
- Distinctive: line 115
Every added or changed behavior has a test, including its error and boundary cases.
“Common” is measured: kept by at least 6 in 10 of the 17 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Unit Testing
Every behavior you added or changed gets a unit test that would fail if that behavior broke. Test through the unit's public interface, match the tests already in the project, and treat coverage as a map of what you missed, never as the goal.
When to use
- You wrote or changed a function, class, module or component and it needs tests.
- The user asks to add unit tests or raise coverage for specific code.
- Unit tests fail after a change and you must decide whether the code or the test is wrong.
Not for: deciding unit vs integration vs end-to-end, test doubles across a whole system, or flaky tests. Use the test-strategy skill for those. When you finish, run the verify-before-done skill.
Workflow
- Detect the framework and conventions. Look for config and existing tests:
- JS/TS:
vitest.config.*,jest.config.*,"test"inpackage.json,*.test.ts/*.spec.ts. - Python:
pytest.ini,[tool.pytest.ini_options]inpyproject.toml,conftest.py,test_*.py. - Go:
*_test.gonext to the code. - Java/Kotlin:
src/test/java, JUnit 5 or Kotest dependencies. - C#:
*.Tests.csprojwith xUnit, NUnit or MSTest. - Rust:
#[cfg(test)] mod testsin the file, ortests/. Open the tests nearest to the code you changed. Copy their file location, naming, fixtures, factories, helpers and assertion style. Never add a second test framework.
- JS/TS:
- List what changed. From the diff, write down each public function or method you added or changed, and each new branch, error path and edge case in it.
- Write the case list before the tests. For each unit:
- Happy path: typical valid input gives the expected output or effect.
- Error paths: invalid input, thrown exceptions, rejected promises, error return values, failed dependencies.
- Boundaries: empty, one, many; zero, negative, min/max; exactly at a limit and one past it;
null/undefined/None; empty string, whitespace, Unicode; duplicates; date and time edges (month end, leap day, time zones). - State: each state transition, and calling things twice or out of order.
- Write the tests. One behavior per test. Name it after the behavior (
rejects_expired_coupon,"returns 0 for an empty cart"). Use Arrange-Act-Assert. Use table-driven tests for many input/output pairs (example below). Assert on outputs and visible effects, not on which private helpers were called. - Keep them deterministic and fast. Inject or fake the clock, random numbers, UUIDs and environment. No network, real database, file system or sleeps in unit tests; fake only those I/O boundaries and leave the logic under test real.
- Prove each new test can fail. Break the code briefly (flip a condition, return a wrong value) or invert the expectation, watch the test fail with a clear message, then revert. A test you never saw fail may be testing nothing.
- Run the new tests, then the whole unit suite with coverage (commands below). Look at uncovered lines in the files you changed. Add tests for uncovered behavior that matters. Leave trivial code (getters, generated code, framework glue) alone.
- Hand off to verification. Run the full project checks with the verify-before-done skill before reporting.
Running with coverage
| Stack | Command | Needs |
| Vitest | npx vitest run --coverage | a coverage provider package, such as @vitest/coverage-v8 |
| Jest | npx jest --coverage | built in |
| pytest | pytest --cov=<package> --cov-report=term-missing | pytest-cov |
| Go | go test -coverprofile=cover.out ./... then go tool cover -func=cover.out | built in |
| Maven | mvn test jacoco:report (report in target/site/jacoco/) | jacoco-maven-plugin configured with prepare-agent |
| Gradle | ./gradlew test jacocoTestReport | the jacoco plugin applied |
| .NET | dotnet test --collect:"XPlat Code Coverage" | the coverlet.collector package in the test project |
| Rust | cargo llvm-cov | the cargo-llvm-cov tool installed |
If the project already has a coverage script (for example npm run test:coverage), use it instead. Adding a coverage package or tool changes the project, so ask the user first.
Coverage is a signal, not a target
- Use the report to find untested behavior: an error branch with no test, a boundary never hit.
- Never write a test only to execute lines. A test with no meaningful assertion raises coverage and catches nothing.
- Don't lower a project's coverage threshold to make CI pass. Don't add exclusions to hide your own new code.
- High coverage with weak assertions is worse than lower coverage with strong ones, because it looks safe.
Table-driven example
The same pattern exists in every framework (it.each / test.each, @pytest.mark.parametrize, Go table tests, JUnit @ParameterizedTest, xUnit [Theory]).
import pytest
from shop.pricing import discount_for
@pytest.mark.parametrize(
"total, expected",
[
(0, 0), # empty cart
(99.99, 0), # just below threshold
(100, 10), # exactly at threshold
(250, 25), # typical
],
)
def test_discount_for_totals(total, expected):
assert discount_for(total) == expected
def test_discount_rejects_negative_total():
with pytest.raises(ValueError, match="negative"):
discount_for(-1)Fixing failing tests
When a unit test fails after a change, decide which side is wrong before touching anything:
| Situation | Action |
| The behavior changed on purpose (new requirement) | Update the test to the new behavior, and say so in your report |
| The behavior changed by accident | Fix the code; leave the test as it is |
| The test relied on internals that were refactored | Rewrite the test against the public behavior |
| A snapshot changed | Read the diff line by line; update only if every change is intended |
| You can't tell which is right | Stop and ask the user, showing the old and new behavior |
Never delete, skip or loosen a failing test just to get green.
Anti-patterns
- Testing private methods directly. Test through the public interface; if a private part needs its own tests, it may deserve its own unit.
- Mocking the thing under test, or mocking so much that the test only checks the mocks.
- Asserting call sequences (
expect(helper).toHaveBeenCalledTimes(3)) instead of results. - Tautological tests that recompute the expected value with the same logic as the code.
- One giant test covering ten behaviors; when it fails you don't know which one broke.
- Snapshot everything and approve every snapshot update without reading it.
- Sleeps and real time in unit tests.
- Tests written after the fact that only pass: never seen failing, so never proven.
Done when
- Every added or changed behavior has a test, including its error and boundary cases.
- Each new test was seen failing once for the right reason.
- New tests follow the existing framework, layout and style.
- The unit suite passes; coverage of the changed files was reviewed, and gaps that matter are tested.
- Any test you changed is listed in your report with the reason.
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.

