Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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):

MetricValue
Line coverage87.5%
Region coverage88.9%
Function coverage77.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 circuits job executes the live UltraHonk round trips (oracle → witness → bb provebb verify), so the 87% figure includes proofs that actually verify, not mocks.
  • Error paths are first-class — every error variant in docs/error-surface.md is 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 behind CRUCIBLE_SOROBAN_LIVE=1; the CLI sits in the 65–95% band because its hard paths (real bb proving) 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:

  1. the happy path (one round trip),
  2. each structural rejection the feature can produce (one per error variant),
  3. 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%.