← Skill library

Code

Test Writer

Writes or updates automated tests for given code or the current diff — detects the project's framework, covers happy path plus edge and error cases, matches existing style, and runs the suite. Use when the user says "write tests", "add test coverage", "test this function", "cover this with tests", "write a unit test for X", or names code to test. Not for reviewing existing tests or writing production code.

✓ HandgeprüftFreeMIT licenseOne folder · SKILL.mdCode

Add it to your agent

Pick a way — each one drops the skill into .claude/skills/.

One short line. Needs Node — works on macOS, Linux & Windows.

Terminal
npx stackscout add test-writer
The full playbookRead it ↓

Test Writer

Write tests that would actually fail if the code broke. Cover behavior, not lines.

Step 1 — Decide what to test

Pick the target, in order:

  1. Code the user named (a function, file, class, or module).
  2. If they said "the diff" or nothing specific: git diff and git diff --cached, and test the changed functions.
  3. If neither yields a target, ask what to test. Do not test the whole repo unprompted.

Read the target in full — the whole function and its callers, not just a signature. You cannot test behavior you have not read.

Step 2 — Detect the framework and conventions

Never assume. Look at what the project already uses:

  • JS/TS — check package.json scripts and devDeps for vitest, jest, mocha, node:test, @playwright/test. Note test/describe/it/expect style already in the repo.
  • Pythonpytest if pytest/conftest.py/pyproject says so, else unittest.
  • Gotesting + table-driven tests (func TestXxx(t *testing.T)).
  • Rust#[cfg(test)] modules with #[test]. Ruby — RSpec vs Minitest.
  • Others — match whatever runner and assertion library is already present.

Open 1–2 existing test files. Copy their structure: imports, naming, setup/teardown, mocking approach, assertion style. Your tests must look like they were already there.

Step 3 — Write focused tests

For each unit under test, cover:

  1. Happy path — the normal input produces the expected output. At least one clear case.
  2. Edge cases — empty/null/undefined, zero and negatives, boundary values (off-by-one), empty collections, very large input, unicode, duplicate or unsorted input.
  3. Error cases — invalid input throws/returns the documented error; failures propagate correctly; nothing is silently swallowed.
  4. Side effects — if it writes a file, calls an API, or mutates state, assert that it did. Mock external I/O (network, clock, filesystem, randomness) so tests are deterministic.

Quality bar, non-negotiable:

  • One behavior per test; a name that states the expected behavior (returns 0 for empty cart), not the method name.
  • Assert on real values, not just "did not throw". A test that always passes is worse than none.
  • Use the arrange–act–assert shape. Keep fixtures small and local; share via existing helpers.
  • Make tests order-independent and repeatable — no shared mutable state, no reliance on wall-clock time, no network. Seed randomness.
  • Do not test trivial getters/setters, framework code, language builtins, or private internals you'd have to reach through reflection to hit. Test the public contract.

Step 4 — Put the files where they belong

Follow the repo's existing layout — do not invent a new one:

  • Colocated foo.test.ts / foo.spec.ts next to foo.ts, or a __tests__/ / tests/ / test/ directory — whichever the project already uses.
  • Go: foo_test.go beside foo.go. Python: tests/test_foo.py or test_foo.py per convention.
  • Add to an existing test file when one already covers that unit; create a new file otherwise.

Step 5 — Run them and report

Run the suite you just wrote with the project's own command (npm test, npx vitest run <file>, pytest path::test, go test ./..., etc.), scoped to the new tests when possible.

  • If they pass: say so, and list what you covered (happy / edge / error) per unit.
  • If a test fails: decide whether the test is wrong or the code has a real bug. Fix a wrong test. If the code looks buggy, do not silently rewrite the test to pass — report the failure and the suspected bug so the user can decide.
  • If you cannot run them (no runner, missing deps), say so plainly and show the exact command to run.

Never claim coverage you did not run. A handful of tests that genuinely exercise the edges beats a wall of asserts that all trivially pass.

✦ or: the whole library at once

Skip the downloads — one MCP connector, every skill right inside your agent, always current.

See the MCP

← all skills