Почему kcov вычисляет неверную статистику покрытия кода для программ Rust?
Я пытался использовать kcov, чтобы получить покрытие кода для библиотеки Rust. Я следовал этому руководству, чтобы собрать и использовать 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
неправильно! Обратите внимание, что функция общедоступна, поэтому ее нельзя оптимизировать из библиотеки:
Здесь мы можем убедиться, что kcov
работает, потому что он может вычислить покрытие кода для одного файла, но не может видеть, что второй файл не покрыт вообще.
В чем здесь проблема? Может быть, тестовые двоичные файлы удаляют неиспользуемые функции и kcov не может их видеть?
2 ответа
Вы правы: на данный момент полностью неиспользуемые функции удаляются, поэтому инструменты покрытия, такие как kcov, хороши только для покрытия ветвлений внутри используемых функций (по крайней мере, суммарная функциональность таких инструментов). Существует некоторая дискуссия о том, чтобы этого не происходило по умолчанию для тестовых / отладочных сборок.
Существует обходной путь: RUSTFLAGS='-C link-dead-code'
переменная окружения. Используйте его при сборке, и компилятор Rust также свяжет мертвый код:
RUSTFLAGS='-C link-dead-code' cargo test