Rust 测试的文档表明,当定义单元测试的模块在范围内时运行单元测试,并激活测试配置标志:
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
}
然而,在大型项目中,经常将测试模块限制到不同的文件中,以便测试模块指向不同:
#[cfg(test)]
#[path = "unit_tests/tests.rs"]
mod tests;
使用此设置,在大型项目中,可能会发生有人删除了 src/unit_tests/tests.rs
的
reference(即上面的代码块),而不删除测试文件本身。这通常表明存在错误:
src/unit_tests/tests.rs
不应保留在存储库中,src/unit_tests/tests.rs
中的测试本应运行,但实际上并未运行,CI 应该对此直言不讳。我想向我项目的 CI 添加一个验证,以确保我的板条箱中不存在此类未固定的测试文件。 Rust 生态系统中是否有任何工具可以帮助我以编程方式检测那些未链接的测试文件?
(如果在板条箱的
tests/
存储库中找到集成测试,则会自动编译,但 IIUC,不适用于单元测试)
有一个问题要求货物进行此检查,货物(发布)应该抱怨未使用的源文件,并从中发现货物模块板条箱可以做到这一点。例如:
//! src/lib.rs
#[cfg(test)]
mod tests;
//! src/tests.rs
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
> cargo modules generate tree --lib --with-orphans --cfg-test
crate mycrate
└── mod tests: pub(crate) #[cfg(test)]
但是,如果我删除
#[cfg(test)] mod tests;
,输出将如下所示:
> cargo modules generate tree --lib --with-orphans --cfg-test
crate mycrate
└── mod tests: orphan
您将能够
grep
表示“孤儿”,并因此导致您的检查失败。
我要说的是,从我的小测试来看,这个工具似乎非常慢。链接问题中的讨论表明,如果在货运中实施,则必须使用更好的方法。
您还必须记住任何其他条件编译可能会产生误报(即您根据体系结构、操作系统或功能合法地包含或排除某些模块)。有一个
--all-features
标志可以帮助解决其中的一些问题。
关于该主题有一个非常古老的 rustc 问题,该问题仍然处于开放状态。
然而,其中一位评论者提供了一个技巧:
实现此目的的一种可能方法(包括作为第三方工具)是解析 rustc 为 Cargo 发出的 .d 文件,并查找任何未提及的 .rs 文件。显然
rg --no-filename '^[^/].*\.rs:$' target/debug/deps/*.d | sed 's/:$//' | sort -u | diff - <(fd '\.rs$' | sort -u)
.d
文件是
makefile 兼容的依赖列表所以我认为他们应该列出项目中所有 Rust 文件之间的关系。这就是为什么如果缺少一个,cargo / rustc 就看不到它。