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.agencyA 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.htmlwith annotated source for every file.--threshold <percent>— exit with code1when 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 code1when any individual file falls below the given value. Combine with--thresholdto 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 60Cleaning collected data
agency coverage cleanRemoves the .coverage/ directory.
Configuration
All options can be set in agency.json so you don't have to repeat them on the command line:
{
"coverage": {
"outDir": ".coverage",
"threshold": 80,
"perFileThreshold": 60,
"exclude": [
"examples/**",
"stdlib/legacy/**",
"**/*.generated.agency"
]
}
}| Field | Type | Description |
|---|---|---|
outDir | string | Directory for collected coverage data. Defaults to .coverage. |
threshold | number (0–100) | Overall coverage minimum. Equivalent to passing --threshold. |
perFileThreshold | number (0–100) | Per-file coverage minimum. Equivalent to passing --per-file-threshold. |
exclude | string[] | 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--coverageflag 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_modulesdirectory are excluded — only user-authored.agencyfiles in your workspace are tracked. - Each process writes a
cov-{pid}-{uuid}.jsonfile on exit so concurrent test workers do not collide. agency coverage reportmerges allcov-*.jsonfiles in the output directory, compiles each target.agencyfile to read its__sourceMapexport, and computes per-file/per-line coverage.