Skip to content

Coverage

Agency includes a step-coverage system that tracks which lines of your .agency source files were exercised by tests. Coverage records every step the runtime executes (function bodies, if/else arms, loop iterations, handlers, etc.) and produces summary, detail, or HTML reports.

Quick start

Run any test command with --coverage:

agency test --coverage tests/
agency test js --coverage tests/

A summary report is printed after the tests finish:

Agency Coverage Report
======================
stdlib/array.agency                      100.0%  (76/76 steps)
stdlib/object.agency                     100.0%  (22/22 steps)
stdlib/math.agency                        33.3%  (2/6 steps)
────────────────────────────────────────────────────────────
Total                                     53.8%  (162/301 steps)

By default each --coverage invocation cleans the previous .coverage/ data first. Pass --accumulate to merge into the existing dataset:

agency test --coverage tests/agency/binop.agency
agency test --coverage --accumulate tests/agency/handlers/

Generating reports

Once coverage data has been collected, generate a report at any time:

agency coverage report stdlib/
agency coverage report --detail stdlib/
agency coverage report --html stdlib/
agency coverage report tests/agency/binop.agency

A target argument is required — it can be a directory (scanned recursively for .agency files) or a single .agency file.

Options

  • --detail — list uncovered line ranges per file.
  • --html — write a self-contained HTML report to .coverage/report/index.html with annotated source for every file.
  • --threshold <percent> — exit with code 1 when total coverage falls below the given value (0–100). Useful in CI to block merges that would drop coverage.
  • --per-file-threshold <percent> — exit with code 1 when any individual file falls below the given value. Combine with --threshold to enforce both an overall minimum and a per-file minimum.

When a threshold is set, the report ends with either ✓ Coverage thresholds met or one or more lines listing the failing files / overall percentage.

agency coverage report stdlib --threshold 80 --per-file-threshold 60

Cleaning collected data

agency coverage clean

Removes the .coverage/ directory.

Configuration

All options can be set in agency.json so you don't have to repeat them on the command line:

json
{
  "coverage": {
    "outDir": ".coverage",
    "threshold": 80,
    "perFileThreshold": 60,
    "exclude": [
      "examples/**",
      "stdlib/legacy/**",
      "**/*.generated.agency"
    ]
  }
}
FieldTypeDescription
outDirstringDirectory for collected coverage data. Defaults to .coverage.
thresholdnumber (0–100)Overall coverage minimum. Equivalent to passing --threshold.
perFileThresholdnumber (0–100)Per-file coverage minimum. Equivalent to passing --per-file-threshold.
excludestring[]picomatch globs of source files to drop from reports and threshold checks. Both absolute and cwd-relative paths are matched, so you can write either form.

CLI flags always override the corresponding config values for that single invocation.

Environment variables

These are normally set automatically by the --coverage flag, but you can also set them manually to enable coverage in any process running compiled Agency code:

  • AGENCY_COVERAGE — when set (to any non-empty value), the runtime collects step hits and writes a JSON file to the configured output directory on process exit.
  • AGENCY_COVERAGE_OUTDIR — overrides the output directory for the JSON files. Defaults to .coverage. Should be an absolute path when subprocesses with different working directories are involved (the --coverage flag handles this for you).

How it works

  • Every step the Agency runtime executes calls into a CoverageCollector. Hits are keyed by ${moduleId}:${scopeName} -> { stepPath: true }.
  • Modules whose path lives under a node_modules directory are excluded — only user-authored .agency files in your workspace are tracked.
  • Each process writes a cov-{pid}-{uuid}.json file on exit so concurrent test workers do not collide.
  • agency coverage report merges all cov-*.json files in the output directory, compiles each target .agency file to read its __sourceMap export, and computes per-file/per-line coverage.