This guide explains how to generate and analyze code coverage metrics for the rustnn project.
rustnn uses cargo-llvm-cov for code coverage analysis. This tool provides accurate coverage data using LLVM's source-based code coverage instrumentation.
As of the latest test run, the project has:
- Total Line Coverage: 47.25% (9,937 / 21,030 lines)
- Total Function Coverage: 42.26% (661 / 1,564 functions)
- Total Region Coverage: 47.38% (15,767 / 33,278 regions)
High coverage modules (>80%):
weight_file_builder.rs: 99.13% linesgraph.rs: 97.14% linesshape_inference.rs: 86.84% linesgraphviz.rs: 92.70% linesvalidator.rs: 72.02% lines
Modules needing attention (<30%):
coreml_mlprogram.rs: 29.56% lines (converter)onnx.rs: 24.57% lines (converter)webnn_json.rs: 26.44% linescoreml.rs: 0% lines (platform-specific executor)loader.rs: 0% lines (needs tests)error.rs: 0% lines (error types, display-only)
The coverage tools are automatically installed when you first run a coverage command. However, you can install them manually:
# Install cargo-llvm-cov
cargo install cargo-llvm-cov
# Install LLVM tools component (required, installed automatically on first run)
rustup component add llvm-tools-previewGenerate a text-based coverage report:
make coverageGenerate and open an HTML report in your browser:
make coverage-openRuns tests with coverage instrumentation and displays a text summary in the terminal.
Output: Text table showing coverage per file Use case: Quick coverage check during development
make coverageGenerates a detailed HTML report with line-by-line coverage visualization.
Output: HTML files in target/llvm-cov/html/
Use case: Deep dive into which lines are covered/uncovered
make coverage-html
# View report at: target/llvm-cov/html/index.htmlGenerates an LCOV-format report suitable for CI/CD integration.
Output: LCOV file at target/llvm-cov/lcov.info
Use case: CI/CD pipelines, integration with coverage services (Codecov, Coveralls)
make coverage-lcov
# Upload to coverage service:
# bash <(curl -s https://codecov.io/bash) -f target/llvm-cov/lcov.infoGenerates HTML report and opens it in your default browser.
Output: HTML report opened in browser Use case: Interactive exploration of coverage data
make coverage-openRemoves all coverage artifacts and instrumentation data.
Use case: Clean build, troubleshooting
make coverage-cleanThe text report shows a table with these columns:
- Filename: Source file path
- Regions: Code regions (branches, functions)
- Missed Regions: Uncovered regions
- Cover: Region coverage percentage
- Functions: Total functions in file
- Missed Functions: Uncovered functions
- Executed: Functions with at least one covered line
- Lines: Total lines of code
- Missed Lines: Uncovered lines
- Cover: Line coverage percentage
Example:
Filename Lines Missed Lines Cover
rustnn/src/shape_inference.rs 2090 275 86.84%
rustnn/src/graph.rs 175 5 97.14%
The HTML report provides:
-
Overview Page (
index.html)- Summary statistics
- Coverage percentages
- List of all source files with coverage
-
File Details
- Line-by-line view of source code
- Color-coded coverage:
- Green: Line covered by tests
- Red: Line not covered
- Gray: Non-executable line (comments, blank)
- Execution counts for each line
- Branch coverage indicators
-
Navigation
- Filter by coverage percentage
- Sort by filename, coverage, etc.
- Click files to see detailed view
The LCOV format is a text-based format that includes:
- Line coverage data (LH, LF metrics)
- Function coverage data (FNH, FNF metrics)
- Branch coverage data (BRH, BRF metrics)
This format is compatible with:
Before committing code:
# Run tests
make test
# Check coverage
make coverage
# If coverage decreased significantly, consider adding tests
make coverage-html
# Open target/llvm-cov/html/index.html to see which lines need coverageAdding new features:
- Write tests alongside new code
- Run
make coverage-opento verify new code is covered - Aim for >80% coverage on new modules
For GitHub Actions or other CI systems:
- name: Generate coverage report
run: make coverage-lcov
- name: Upload to Codecov
uses: codecov/codecov-action@v3
with:
files: target/llvm-cov/lcov.info
fail_ci_if_error: trueProject Goals:
- Overall line coverage: >60% (current: 47.25%)
- Core modules (graph, shape_inference, validator): >80%
- New code: >70% coverage required
Current Focus Areas:
- Converters (ONNX, CoreML) - Low coverage due to integration testing needs
- Executors - Platform-specific, some modules not testable in all environments
- Error handling paths - Often not covered in happy-path tests
Focus on testing individual functions in isolation:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_my_function() {
let result = my_function(input);
assert_eq!(result, expected);
}
}Don't forget to test failure cases:
#[test]
fn test_invalid_input() {
let result = my_function(invalid_input);
assert!(result.is_err());
}Create helper functions for common test setups:
fn create_test_graph() -> GraphInfo {
// Build a standard test graph
}
#[test]
fn test_with_fixture() {
let graph = create_test_graph();
// Test graph operations
}Test multiple inputs efficiently:
#[test]
fn test_data_type_sizes() {
let test_cases = vec![
(DataType::Float32, 4),
(DataType::Float16, 2),
(DataType::Int32, 4),
];
for (dtype, expected_size) in test_cases {
assert_eq!(dtype.bytes_per_element(), expected_size);
}
}For converters and executors, add integration tests that exercise the full pipeline.
Use #[cfg(not(coverage))] to exclude code that shouldn't be covered:
#[cfg(not(coverage))]
fn debug_only_function() {
// This code won't be included in coverage metrics
}Common exclusions:
- Debug/print functions
- Platform-specific code not testable in CI
- Generated code
- Trivial getters/setters
error: no such command: `llvm-cov`Solution: Install cargo-llvm-cov:
cargo install cargo-llvm-coverror: llvm-tools-preview component is not installedSolution: The tool will prompt to install, or run manually:
rustup component add llvm-tools-previewIf coverage seems incorrect after code changes:
make coverage-clean
make coverage-htmlIf you get build errors during coverage:
- Ensure regular tests pass first:
make test - Clean and rebuild:
cargo clean && make coverage - Check for feature flag issues - coverage runs with
--all-features
- Use
make coveragefor quick checks - Use
make coverage-openfor detailed analysis - Use
make coverage-lcovfor CI integration - Aim for >70% coverage on new code
- Focus on testing core logic and error paths
- Run coverage before committing significant changes