Test coverage
The project tracks line and region coverage across the whole workspace (libraries, adapters, and CLI). Coverage is a floor, not a target: the CI gate and the honest bar is ≥ 80% overall line coverage, with the crypto, verifier, and adapter modules held to the same standard as everything else.
Current status
Measured with cargo-llvm-cov over the full workspace (all targets,
excluding generated test-vectors/ fixtures and the committed on-chain proof
artifacts):
| Metric | Value |
|---|---|
| Line coverage | 87.5% |
| Region coverage | 88.9% |
| Function coverage | 77.5% |
The low-function figure is an artifact of counting: CLI command entry points,
trait impls, and error-variant constructors drag the function average down
while the code paths that matter (crypto backend, verifier routing, adapter
translation, witness handling) sit in the 85–100% band. The per-module table
at the bottom of a cargo llvm-cov report run shows the detail.
How to reproduce
cargo install cargo-llvm-cov # once
cargo llvm-cov --workspace --all-targets \
--ignore-filename-regex '(target/|test-vectors/|onchain/)'
Measure with the toolchain on PATH. The CI gate runs in the noir circuits job, where nargo and bb are installed, so the real-crypto
suites (UltraHonk round trips, the simulator e2e, the Soroban agreement
suite) count toward the measurement. Run without them (cargo test --workspace alone) and those suites are skipped, dropping the reading
below the floor even though no production code regressed — the gate is a
floor on the full-toolchain number, not the fastest number.
What the coverage buys
- Real-crypto suites run in CI — the
noir circuitsjob executes the live UltraHonk round trips (oracle → witness →bb prove→bb verify), so the 87% figure includes proofs that actually verify, not mocks. - Error paths are first-class — every error variant in
docs/error-surface.mdis raised by at least one test: structural rejections (wrong key, wrong circuit, missing state binding) are asserted without needing a toolchain, and toolchain-gated paths are covered by the gated live suites. - The weak modules are the honest ones — the local network client
(
live.rs) sits just above 74% because its failure branches (malformed RPC responses, strkey type mismatches) are unit-tested while the network happy path is gated behindCRUCIBLE_SOROBAN_LIVE=1; the CLI sits in the 65–95% band because its hard paths (realbbproving) need the full toolchain, which the CI circuits job supplies.
Adding coverage responsibly
More tests are welcome; padding is not. A test that asserts a branch without changing what would break if the branch regressed adds inventory, not safety. When adding a feature, cover:
- the happy path (one round trip),
- each structural rejection the feature can produce (one per error variant),
- the boundary conditions (empty input, maximum input, wrong type).
Then re-run the measurement above and confirm the module’s coverage did not regress below 80%.