Skip to content

Latest commit

 

History

History
95 lines (66 loc) · 3.5 KB

File metadata and controls

95 lines (66 loc) · 3.5 KB

Code Coverage

Definition

Code Coverage is a metric used in software testing to measure the percentage of a program's source code that is executed when a particular test suite is run. It helps to identify areas of the code that are not being tested.

Why is Code Coverage Important?

  • Identify Untested Code: Highlights parts of the codebase that are not exercised by any tests.
  • Assess Test Suite Effectiveness: Provides an indication of how thoroughly the existing tests cover the application's logic.
  • Improve Test Quality: Encourages developers to write more comprehensive tests.
  • Refactoring Confidence: High coverage provides more confidence when refactoring.

Types of Code Coverage

  • Line Coverage: Percentage of executable lines of code that have been executed.
  • Branch Coverage: Percentage of decision points (e.g., if statements) where all possible outcomes have been executed.
  • Function/Method Coverage: Percentage of functions or methods that have been called.

How to Generate a Code Coverage Report in Rust

We can use the cargo-llvm-cov tool to generate code coverage reports for Rust projects.

1. Install cargo-llvm-cov

cargo install cargo-llvm-cov

2. Create a simple Rust project

cargo new coverage_example --lib
cd coverage_example

3. Write some code and tests (src/lib.rs)

pub fn is_adult(age: u32) -> bool {
    if age >= 18 {
        true
    } else {
        false
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_is_adult_with_adult_age() {
        assert!(is_adult(20));
    }
}

4. Generate the coverage report

cargo llvm-cov --html

This will generate an HTML report in the target/llvm-cov/html directory. Open the index.html file in your browser to see the report.

Interpreting the Report and Improving Coverage

The report will show that the is_adult function has only 50% branch coverage because the else branch was not tested. To improve the coverage, we can add a test for a non-adult age:

// In tests mod
#[test]
fn test_is_adult_with_non_adult_age() {
    assert!(!is_adult(16));
}

Now, if you run cargo llvm-cov --html again, the report will show 100% line and branch coverage.

Code Coverage Best Practices

  • Set Realistic Targets: Aim for a reasonable coverage target (e.g., 80-90%), but don't strive for 100% at all costs.
  • Focus on Critical Code: Prioritize coverage for complex and critical parts of the codebase.
  • Use Coverage as a Guide: Use coverage reports to identify untested code, but don't rely on them as the sole measure of quality.
  • Integrate with CI/CD: Automate coverage generation in your CI/CD pipeline to track trends and enforce minimum thresholds.

Limitations of Code Coverage

  • Doesn't Measure Test Quality: 100% coverage does not mean the tests are good or that the code is bug-free. It only means the code was executed.
  • Can be Misleading: It's possible to have high coverage but still have bugs if the tests don't cover all edge cases.

Conclusion

Code Coverage is a valuable metric for assessing the thoroughness of a test suite and identifying untested areas of a codebase. While not a silver bullet for quality, it serves as a useful indicator and a tool for continuous improvement. Rust's strong testing capabilities, combined with powerful tools like cargo-llvm-cov, make it straightforward to integrate code coverage into the development workflow.