13

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

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

货运.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));
    }
}

src/subm.rs

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

#[cfg(test)]
mod test {
    #[test]
    fn test_coverage2() {
    }
}

有两个相同的函数,一个在 crate 的根中,另一个在子模块中。唯一的区别是第一个测试刺激了一个功能,而另一个则什么都不做。在这种情况下,我希望覆盖率不超过 50%。

然而kcov报告这个:

报道摘要

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

覆盖范围1

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

覆盖范围2

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

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

4

2 回答 2

14

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

RUSTFLAGS='-C link-dead-code' cargo test
于 2016-07-14T10:23:21.333 回答
5

您是对的:目前完全未使用的功能被剥离,因此像 kcov 这样的覆盖工具仅适用于使用过的功能内的分支覆盖(至少,这些工具的摘要功能)。有一些关于使测试/调试版本默认不发生这种情况的讨论。

于 2015-09-11T12:00:11.887 回答