为什么kcov会为Rust程序计算错误的代码覆盖率统计信息?

mbr*_*brt 12 code-coverage rust kcov

我试图使用kcov来获取Rust库的代码覆盖率.我已经按照本教程构建和使用kcov.报道似乎有效,但我面临着一个奇怪的高覆盖率.项目中的某些文件获得100%的覆盖率,即使它们实际上根本没有被覆盖!

这是一个重现问题的最小项目:

Cargo.toml

[package]
name = "mypackage"
version = "0.1.0"
authors = ["mbrt"]
Run Code Online (Sandbox Code Playgroud)

SRC/lib.rs

pub mod subm;

pub fn coverage1(i : bool) -> bool {
    if i {
        true
    }
    else {
        false
    }
}

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

    #[test]
    fn test_coverage1() {
        assert!(coverage1(true));
    }
}
Run Code Online (Sandbox Code Playgroud)

SRC/subm.rs

pub fn coverage2(i : bool) -> bool {
    if i {
        true
    }
    else {
        false
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn test_coverage2() {
    }
}
Run Code Online (Sandbox Code Playgroud)

有两个相同的功能,一个在箱子的根部,另一个在子模块中.唯一的区别是第一次测试刺激了一个功能,而另一个没有做任何事情.在这种情况下,我预计覆盖率不会超过50%.

kcov报告如下:

报道摘要

覆盖范围lib.rs是正确的:

覆盖率2

但覆盖范围subm.rs是错误的!请注意,该函数是公共的,因此无法从库中进行优化:

coverage2

在这里,我们可以验证它kcov是否正常工作,因为它能够计算一个文件的代码覆盖率,但是它根本无法看到第二个文件根本没有被覆盖.

这里有什么问题?也许测试二进制文件删除未使用的函数,kcov无法看到它们?

mbr*_*brt 12

有一种解决方法:RUSTFLAGS='-C link-dead-code'环境变量.在构建时使用它,Rust编译器也会链接死代码:

RUSTFLAGS='-C link-dead-code' cargo test
Run Code Online (Sandbox Code Playgroud)


huo*_*uon 5

你是对的:目前剥离了完全未使用的函数,因此像kcov这样的覆盖工具只适用于已使用函数中的分支覆盖(至少,这些工具的摘要功能).有一些讨论有关使测试/调试建立此默认情况下不发生.