What it does
dev-coverage drives cargo-llvm-cov
against your project, parses the JSON output, and emits results as a
dev-report::Report. It compares against a
stored baseline so CI gates, release pipelines, and AI assistants can
act on coverage regressions without scraping free-form text.
Why a separate crate
Test coverage is the single most direct way to ask "how much of this code is actually exercised?" Without it, every other quality check is an opinion. With it, you can answer "did this PR drop line coverage below 80%?" or "did this PR introduce a 5-point regression vs. main?" as a yes/no decision.
dev-coverage makes those questions programmable, not interactive.
Quick start
[]
= "0.9"
One-time tool install:
Drive it from code:
use ;
let run = new;
let result = run.execute?;
let threshold = min_line_pct;
let check = result.into_check_result;
// `check` is a `dev_report::CheckResult` ready to push into a Report.
# Ok::
Threshold types
| Threshold | What it measures |
|---|---|
CoverageThreshold::MinLinePct |
Percent of executable lines exercised by tests. |
CoverageThreshold::MinFunctionPct |
Percent of functions called by at least one test. |
CoverageThreshold::MinRegionPct |
Percent of basic blocks (branch points) exercised. |
Line coverage is the most common. Region coverage is the strictest.
Baseline workflow
The headline feature beyond raw measurement: persist a baseline, then flag regressions on the next run.
use ;
let run = new;
let result = run.execute?;
let store = new;
// Compare against last run on main.
if let Some = store.load?
// Persist for next time.
store.save?;
# Ok::
JsonFileBaselineStore writes one <root>/<scope>/<name>.json per
baseline with atomic write-temp-rename semantics; a partial write that
survives a crash will not corrupt the comparison on the next run.
Producer integration
CoverageProducer plugs coverage into a multi-producer pipeline driven
by dev-tools:
use ;
use Producer;
let producer = new;
let report = producer.produce;
println!;
When a baseline is wired in via with_baseline, the producer pushes a
second CheckResult named coverage::regression::<subject> carrying
the deltas in its detail field, with verdict Fail (Error) if the
regression exceeds the tolerance.
Examples
| File | What it shows |
|---|---|
examples/basic.rs |
Run coverage against the current crate; emit a CheckResult. |
examples/with_threshold.rs |
Every CoverageThreshold variant against a constructed result. |
examples/baseline.rs |
Save a baseline, then diff a new run against it. |
examples/producer.rs |
Wrap a run in CoverageProducer (gated by DEV_COVERAGE_EXAMPLE_RUN). |
Requirements
cargo-llvm-cov must be
installed on the system. The crate detects absence and surfaces a
CoverageError::ToolNotInstalled rather than panicking.
The crate's own dependency footprint is small: dev-report, serde,
serde_json.
Migration from 0.1.0
CoverageResult gained branch_pct, total_functions,
covered_functions, total_regions, covered_regions, and files.
If you constructed CoverageResult literals in 0.1.0, fill in the
new fields:
# use CoverageResult;
let _r = CoverageResult ;
The constructor surface (CoverageRun::new, CoverageThreshold::min_*,
CoverageResult::into_check_result) is unchanged.
The dev-* collection
dev-coverage ships independently and is also re-exported by the
dev-tools umbrella crate as
the coverage feature. Sister crates cover the other verification
dimensions:
dev-report— report schema everything emitsdev-fixtures— deterministic test fixturesdev-bench— performance and regression detectiondev-async— async runtime verificationdev-stress— stress and soak workloadsdev-chaos— fault injection and recovery testingdev-security— CVE / license / banned-crate auditdev-deps— unused / outdated dep detectiondev-ci— GitHub Actions workflow generatordev-fuzz— fuzz testing workflowdev-flaky— flaky-test detectiondev-mutate— mutation testing
Status
v0.9.x is the pre-1.0 stabilization line. The API is feature-complete
for coverage measurement, baseline storage, and regression detection.
Production use is fine; 1.0 will pin the public API and the wire
format.
Minimum supported Rust version
1.85 — pinned in Cargo.toml via rust-version and verified by the
MSRV job in CI.
License
Apache-2.0. See LICENSE.