Testing

Test Coverage Reporter

Turn a coverage report into a short, prioritized list of the specific untested branches that actually carry risk -- not a percentage to chase.

When to use this

  • After running a coverage tool, to turn raw output into an actionable list.
  • Before a release, to check the highest-risk paths (payments, auth, data writes) have coverage.
  • Not for chasing a coverage percentage target as a goal in itself -- 100% coverage with weak assertions is worse than 80% with real ones.

The skill file

Copy this verbatim. It's written in the SKILL.md format (YAML frontmatter + markdown instructions) that Claude Code, and increasingly other agent tools, read directly.

SKILL.md
---
name: test-coverage-reporter
description: Read a coverage report (or infer coverage by reading tests against source) and produce a short, risk-ranked list of untested code paths -- not a percentage number. Use after tests exist and a coverage tool has run, or when asked to assess test risk.
---

# Test Coverage Reporter

The percentage is the least useful number in a coverage report. The useful
part is *which specific branch* is untested and *what happens if it's
wrong*.

## Process

1. Get the coverage report (line/branch coverage tool output) or, absent
   one, read each source file against its test file to infer which
   branches have no corresponding test case.
2. For each uncovered branch, assess actual risk: does it handle money,
   auth, data deletion, or external input? Or is it a debug-only log
   statement?
3. Rank by risk, not by raw uncovered-line count -- ten uncovered lines in
   a logging helper matter less than two uncovered lines in a permission
   check.

## Output format

A short table: file:line, what the uncovered branch does, why it matters
(or a note that it's low-risk and can be ignored), and a one-line
suggestion for what the test would need to set up.

Close with a one-sentence verdict: is this codebase's test suite covering
the parts that would actually hurt in production, or not.

Installing it elsewhere

The frontmatter/body split above is Claude Code's convention. Here's how to carry the same instructions into other tools:

Claude Code
.claude/skills/test-coverage-reporter/SKILL.md

Save the file below verbatim (frontmatter included) at that path, project-local or in ~/.claude/skills/ for a user-level skill. Claude Code loads the name/description pair to decide when to pull it in, or you invoke it directly as /test-coverage-reporter.

Cursor
.cursor/rules/test-coverage-reporter.mdc

Convert the YAML frontmatter to Cursor's rule format (description, globs, alwaysApply: false) and keep the markdown body as the rule content. Cursor surfaces it by description match, same idea as Claude Code's auto-load.

Codex CLI / Copilot
AGENTS.md

Codex CLI (and increasingly other agentic CLIs) read AGENTS.md at the repo root as always-on instructions. Paste the markdown body under a heading like ## {title}; for GitHub Copilot's coding agent, the equivalent file is .github/copilot-instructions.md.

Windsurf
.windsurfrules

Append the markdown body to .windsurfrules at the repo root. Windsurf treats the whole file as always-on context, so keep only the instructions you want applied on every request.

Where this goes wrong
  • Reporting every uncovered line with equal weight instead of ranking by what breaks if it's wrong.
  • Treating coverage percentage as the goal -- a suite can hit high coverage with assertions too weak to catch real regressions.
  • Flagging generated code, vendored dependencies, or trivial getters as coverage gaps.