为什么 kcov 计算 Rust 程序的代码覆盖统计数据不正确?
Why does kcov calculate incorrect code coverage statistics for Rust programs?
我尝试使用 kcov to get code coverage for a Rust library. I've followed this tutorial 来构建和使用 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));
}
}
src/subm.rs
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
的报道是错误的!注意函数是public,所以无法从库中优化出来:
在这里我们可以验证 kcov
是否正常工作,因为它能够计算一个文件的代码覆盖率,但无法看到第二个文件根本没有被覆盖。
这里有什么问题?也许测试二进制文件会删除未使用的函数,而 kcov 看不到它们?
你是对的:目前完全未使用的函数被剥离,因此像 kcov 这样的覆盖工具只适用于已使用函数内的分支覆盖(至少,此类工具的摘要功能)。对于 test/debug 个构建,默认情况下 some discussion 不会发生这种情况。
有一个解决方法:RUSTFLAGS='-C link-dead-code'
环境变量。在构建时使用它,Rust 编译器也会 link 死代码:
RUSTFLAGS='-C link-dead-code' cargo test
我尝试使用 kcov to get code coverage for a Rust library. I've followed this tutorial 来构建和使用 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));
}
}
src/subm.rs
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
的报道是错误的!注意函数是public,所以无法从库中优化出来:
在这里我们可以验证 kcov
是否正常工作,因为它能够计算一个文件的代码覆盖率,但无法看到第二个文件根本没有被覆盖。
这里有什么问题?也许测试二进制文件会删除未使用的函数,而 kcov 看不到它们?
你是对的:目前完全未使用的函数被剥离,因此像 kcov 这样的覆盖工具只适用于已使用函数内的分支覆盖(至少,此类工具的摘要功能)。对于 test/debug 个构建,默认情况下 some discussion 不会发生这种情况。
有一个解决方法:RUSTFLAGS='-C link-dead-code'
环境变量。在构建时使用它,Rust 编译器也会 link 死代码:
RUSTFLAGS='-C link-dead-code' cargo test