add-test-coverage
v1.0.0Add meaningful tests for a file, module, or function that lacks them — auto-detect the project's test framework and conventions, cover the happy path, edge cases, and error paths, then run the suite to confirm the new tests pass and actually exercise the target code.
by VladoIvankovic · 0 installs · updated 6/16/2026
Install
/skills install VladoIvankovic/add-test-coverageRuns in any Codeep session (TUI, Zed, or VS Code extension). Writes to .codeep/skills/add-test-coverage/SKILL.md in your project.
SKILL.md
---
name: add-test-coverage
description: Add meaningful tests for a file, module, or function that lacks them — auto-detect the project's test framework and conventions, cover the happy path, edge cases, and error paths, then run the suite to confirm the new tests pass and actually exercise the target code.
allowed-tools: [read_file, write_file, edit_file, create_directory, list_files, search_code, execute_command]
triggers: [add tests, test coverage, write unit tests, cover this file, untested code]
version: 1.0.0
author: Codeep
---
# add-test-coverage
Write tests that genuinely exercise a specific target (file / module / function). Match the project's existing style — do not introduce a new framework.
## Steps
1. **Identify the target.** If the user named a file/function, use it. Otherwise ask, or pick the largest untested file in the change. Read it fully with `read_file` and list every exported function, class, branch, and thrown error you must cover.
2. **Detect the framework + conventions.** Read `package.json` (`scripts.test`, `devDependencies`), or `pyproject.toml` / `pytest.ini` / `Cargo.toml` / `go.mod`. Use `list_files` + `search_code` to find a sibling test (`*.test.ts`, `*.spec.js`, `__tests__/`, `test_*.py`, `*_test.go`, `tests/`). Open 1–2 of them and copy their layout: import style, runner (`jest`/`vitest`/`mocha`/`pytest`/`go test`/`cargo test`), assertion lib, mocking approach, fixtures, naming.
3. **Run the existing suite first** with `execute_command` (e.g. `npm test`, `pytest -q`, `go test ./...`, `cargo test`). Confirm it's green and you know the exact command — that's your feedback loop.
4. **Author the test file** in the conventional location/name with `write_file` (or `edit_file` to extend an existing one). Cover, with descriptive names:
- **Happy path** — typical inputs → expected outputs / state.
- **Edge cases** — empty/null/zero, boundaries, large input, unicode, duplicates, ordering.
- **Error paths** — invalid input throws/rejects/returns the right error; assert the message or type, not just "it threw".
- **Async** — await promises; assert rejections explicitly. Mock I/O, network, clock, and randomness — never hit real services.
5. **Run the new tests** with the command from step 3. Iterate until green. Fix the *test* if expectations are wrong; if a test surfaces a real product bug, stop and report it rather than weakening the assertion to pass.
6. **Verify the tests bite.** Confirm assertions are non-trivial. If coverage tooling exists (`--coverage`, `pytest --cov`, `go test -cover`), run it on the target and confirm the new lines/branches are hit. Sanity-check by mentally (or actually) breaking the target — a passing test on broken code is worthless.
## On failure
- **Runner won't start / deps missing:** install via the project's manager (`npm ci`, `pip install -e .[test]`) — do not switch frameworks. If it still won't run, report the blocker and stop.
- **Target needs deps you can't fake:** introduce mocks/stubs in the test only; never edit production code to make it testable without flagging it first.
- **Flaky test:** remove time/order/network nondeterminism (fake timers, seed RNG, fixed clock) rather than adding retries.
## Done when
The new tests live in the right place, follow the project's style, cover happy + edge + error paths for the target, the full suite passes via the project's own command, and the assertions demonstrably fail if the target's behavior regresses. Report the command run, the count of added tests, and any product bug you uncovered.
## Notes
- Don't test the framework or language built-ins; test *this* code's logic and contracts.
- Keep tests isolated and order-independent — no shared mutable state between cases.
- One behavior per test; prefer table/parametrized cases for input matrices where the project already does.
- Cross-platform: never hardcode `/tmp` or OS paths — use the test framework's tmpdir helpers.