Skip to main content
Watchfire
Test coverage

Backfill tests on an under-covered module

Pin the coverage bar in acceptance criteria — and make the agent earn it.

Who this is for.

You inherited a module that nobody covered properly. Coverage is in the 30s, every PR adds a little, nobody ever does the boring sweep. You want to point an agent at it with a real bar to clear — a failing test, a missing edge case, a coverage threshold — and only call the task done when the bar is actually met.

The workflow in 4 steps.

  1. Encode the bar in the acceptance criteria

    Write the criterion as a measurable outcome — `npm run coverage` on `lib/foo/**` lands above 85%, the regression for issue #341 has a test, the branch in `parse()` that swallows errors gets covered. The task isn't done until that command exits 0.

  2. Point the prompt at real cases, not 'add tests'

    Give the prompt the actual situations to cover: the bug repro, the edge cases your team has hit, the inputs that today blow up at runtime. Vague 'add tests' tasks produce vague tests; specific cases produce tests that catch the next regression.

  3. Run inside the sandboxed worktree

    Watchfire spins the task up in its own worktree with the sandbox on. The agent can run the test runner, read coverage reports, and iterate locally — but it can't ssh out or rewrite global config. You get coverage that came from real test runs, not made-up assertions.

  4. Reject 'snapshot it and move on'

    Review the diff with the acceptance criteria open. If a test only asserts the function didn't throw, send it back with sharper criteria — 'a test must fail on `main` when the assertion is inverted'. Tighten until the test actually proves the behaviour.

A real task you can copy.

Drop this into .watchfire/tasks/<n>.yaml, tweak it to your repo, and start it from the TUI or GUI.

task_id: tst00004
task_number: 4
title: "Backfill tests for lib/parse-csv.ts to 90% line coverage"
prompt: |
  `lib/parse-csv.ts` sits at 41% line coverage and
  has been the source of three recent bugs:
  - Quoted commas inside fields were split as
    column boundaries (#312).
  - Trailing newlines produced an empty trailing
    row (#327).
  - CRLF line endings doubled the row count on
    Windows-exported files (#341).

  Add tests under
  `lib/parse-csv.test.ts` covering at minimum:
  - A field containing a quoted comma.
  - A file ending with one and with two newlines.
  - A file using `\r\n` line endings.
  - An empty file (zero rows, no error).
  - A header-only file (zero data rows).

  Use the existing Vitest setup. Do not change
  `lib/parse-csv.ts` — if a test surfaces a real
  bug, leave it failing and add a TODO comment
  with the issue number.
acceptance_criteria: |
  - `npm run coverage -- lib/parse-csv.ts` reports
    \>= 90% line coverage on that file.
  - All the listed cases above exist as named
    `it(...)` blocks.
  - `npm run test` passes (except for any
    intentionally-failing test added per the
    prompt — those must be marked `it.fails(...)`
    with the issue number).
  - No changes outside `lib/parse-csv.test.ts`.
status: ready

More starters in the task template library.

Why Watchfire makes this faster.

  • Acceptance criteria pin the test bar in machine-checkable form — coverage thresholds, named cases, runner exit code — so 'I added a test' isn't the same as 'the task is done'.
  • The agent runs the test runner inside the worktree, so the coverage numbers come from real runs you can re-verify, not from the agent's belief that the tests probably pass.
  • Sandboxing keeps the agent from monkey-patching CI config or coverage exclusions to 'fix' the threshold — the path to passing is to actually add the test.
  • Each module can have its own task, so you can run a coverage sweep across half a dozen modules in parallel without stepping on each other's runs.
  • The transcript records exactly which cases the agent considered and which it skipped, so a reviewer can spot 'oh, you never tested CRLF' before merge instead of after.
Ready to go

Get started with Watchfire

Install in seconds. Define tasks. Let agents ship code for you.

Download for macOS

Available for macOS, Linux, and Windows

install
# Install via Homebrew (macOS)
$brew tap watchfire-io/tap
$brew install --cask watchfire-io/tap/watchfire
# Set up your project and go
$watchfire init
$watchfire task add "Build the login page"
$watchfire start --all

Includes GUI, CLI, and daemon. Also available via Homebrew.