Course contentsShow
← Rust
Lesson 1645 of 1,91014. System Integration and EcosystemFree lesson

Measuring Code Coverage

You will utilize llvm-cov to identify untested paths in performance-critical codebases.

In this lesson, you will learn how to use llvm-cov to pinpoint untested execution paths within performance-critical Rust codebases.

Leveraging LLVM Instrumentation

When working on high-performance libraries, simply running tests isn't enough; you must ensure your critical hot paths are actually executed. Rust leverages LLVM’s native profiling tools to generate precise branch-level coverage data. Unlike simple line-based counters, llvm-cov tracks which branches were taken, allowing you to see if your error-handling logic—often bypassed in "happy path" testing—is truly robust.

Setting Up Coverage

To measure coverage, you must compile your code with the -C instrument-coverage flag. This injects counters into your binary that track execution frequency. You can enable this easily for your current workspace:

# Set the environment variable to enable instrumentation
export RUSTFLAGS="-C instrument-coverage"

# Run tests to generate raw coverage data
cargo test

After running cargo test, you will find .profraw files in your target directory. These files contain the binary mapping of your execution.

Generating Reports

To visualize these results, you need llvm-profdata and llvm-cov (part of the LLVM toolchain). You can aggregate these using the cargo-llvm-cov cargo sub-command, which automates the heavy lifting of merging profiling data and mapping it back to your source files:

# Generate a human-readable report in your terminal
cargo llvm-cov report --use-color --summary-only

Identifying Untested Paths

In performance-critical systems, branch mispredictions can be costly. By inspecting the output, look specifically for branches marked with 0 execution counts. These often represent edge cases, like buffer boundary checks or rare hardware failures. If your "fast path" is covered but your "recovery logic" is at 0%, your system may be vulnerable to panics or undefined behavior when encountering malformed input, even if your main integration tests pass. By visualizing these gaps, you can write targeted property-based tests to force execution into those neglected branches.

Key Takeaway: Use llvm-cov to transform opaque test suites into high-resolution maps of your codebase, ensuring that critical error-handling paths are as battle-tested as your optimized fast paths.