我試圖使用kcov來獲取Rust庫的代碼覆蓋率。我遵循this tutorial來構建和使用kcov。覆蓋似乎工作,但我面臨一個奇怪的高覆蓋率。項目中的某些文件可以獲得100%的覆蓋率,即使它們實際上沒有被覆蓋!爲什麼kcov會爲Rust程序計算不正確的代碼覆蓋率統計信息?
這是一個很小的項目重現問題:
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
覆蓋率是錯誤的!請注意該函數是公共的,所以它不能從庫優化掉了:
在這裏,我們可以驗證kcov
工作,因爲它能夠計算代碼覆蓋率爲一個文件,但它是無法看到第二個文件沒有被覆蓋。
這裏有什麼問題?也許測試二進制文件剝離未使用的函數,kcov看不到它們?
*該函數是公共的,所以它不能從庫中優化* - 它絕對可以。所有東西都是靜態編譯的,所以編譯器知道在創建二進制文件時使用了哪些函數(以及如何!)。由於單態化,這是一個巨大的好處。 – Shepmaster
@Shepmaster好點,我沒有想過。 – mbrt