为什么kcov为Rust程序计算错误的代码覆盖率统计数据?

为什么kcov为Rust程序计算错误的代码覆盖率统计数据?,rust,code-coverage,kcov,Rust,Code Coverage,Kcov,我试着用它来获得一个生锈库的代码覆盖率。我已经遵循了kcov的构建和使用方法。覆盖率似乎有效,但我面临着一个奇怪的高覆盖率。项目中的一些文件得到了100%的覆盖率,即使它们实际上根本没有被覆盖 这是一个再现问题的最小项目: Cargo.toml [package] name = "mypackage" version = "0.1.0" authors = ["mbrt"] src/lib.rs pub mod subm; pub fn coverage1(i : bool) -> b

我试着用它来获得一个生锈库的代码覆盖率。我已经遵循了kcov的构建和使用方法。覆盖率似乎有效,但我面临着一个奇怪的高覆盖率。项目中的一些文件得到了100%的覆盖率,即使它们实际上根本没有被覆盖

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

Cargo.toml

[package]
name = "mypackage"
version = "0.1.0"
authors = ["mbrt"]
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));
    }
}
pub fn coverage2(i : bool) -> bool {
    if i {
        true
    }
    else {
        false
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn test_coverage2() {
    }
}
src/subm.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));
    }
}
pub fn coverage2(i : bool) -> bool {
    if i {
        true
    }
    else {
        false
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn test_coverage2() {
    }
}
有两个相同的函数,一个在板条箱的根目录中,另一个在子模块中。唯一的区别是,第一个测试刺激一个功能,而另一个完全不起作用。在这种情况下,我希望保险范围不超过50%

但是
kcov
报告:

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

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

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


这里有什么问题?也许测试二进制文件剥离了未使用的函数,而kcov却看不到它们?

你是对的:目前完全未使用的函数都被剥离了,所以像kcov这样的覆盖工具只适用于已使用函数中的分支覆盖(至少是此类工具的摘要功能)。对于测试/调试构建,有一个关于在默认情况下不发生这种情况的方法。

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

RUSTFLAGS='-C link-dead-code' cargo test

我想,当“覆盖”开关打开时,这些功能至少应该保持不变。@MatthieuM。问题是,据我所知,情况并非如此。@brt:的确,这相当有趣。@MatthieuM。目前没有“覆盖范围”切换(kcov只是依靠标准的DWARF调试信息)。@huon dbaupp:老实说,我想说这是kcov中的一个bug(尽管可能是因为它与语言无关);至少它应该报告被忽略行的百分比(以及它们是什么)。该函数是公共的,因此不能从库中优化它-它绝对可以。所有内容都是静态编译的,因此编译器在创建二进制文件时知道使用了哪些函数(以及如何使用)。这是一个巨大的好处,由于单晶。@Shepmaster很好的一点,我没有考虑它。