ust*_*ion 10 unit-testing rust
我有crate-0,src/lib.rs如下:
#[cfg(test)]
pub mod test_utils {
pub struct OnlyInTests(pub usize);
pub fn helper() -> usize { 999 }
#[test]
fn test_0() { let _ = OnlyInTests(helper()); }
}
Run Code Online (Sandbox Code Playgroud)
我也有crate-1,我需要在crate-0中定义的测试框架:
extern crate crate_0;
#[cfg(test)]
pub mod test_utils {
// This will error out - cannot find mod test_utils in crate_0
use crate_0::test_utils::{OnlyInTests, helper()};
#[test]
fn test_1() { let _ = OnlyInTests(helper()); }
}
Run Code Online (Sandbox Code Playgroud)
这里的代码很简单,可以复制粘贴,但实际上我有复杂的测试工具,我想在测试crate-1时使用它.
我无法将测试实用程序分离到不同的包中,因为我会得到循环依赖性错误:test_utils将依赖于crate-0创建内容并crate-0依赖于test_utils测试).我也不想这样做,因为还有更多的板条箱,其测试实用程序我想在依赖板条箱中使用.
两种解决方案的权衡截然不同:
将您的测试实用程序而不是您的测试放入新的箱子中crate-0-testutils。使crate-0dev 依赖于crate-0-testutils; crate-0-testutils取决于crate-0; crate-1dev-depend 依赖crate-0-testutils于 crate-0。
这不会创建循环依赖关系,因为开发依赖关系不会传播。由于开发依赖性,您在 crate-0 中的测试仍然可以使用 crate-0-testutils 中的内容。
如果您的所有创建都具有此类实用程序,则这最多会使您的库箱数量增加一倍。
创建一个不依赖于任何东西Cargo.toml的功能:crate-0
[features]
testing = []
Run Code Online (Sandbox Code Playgroud)
其中之一crate-1取决于上述内容:
testing = ["crate-0/testing"]
Run Code Online (Sandbox Code Playgroud)
然后,在未启用该功能时,使每个板条箱上的第一次测试失败,以便更容易理解错误:
#[cfg(all(not(feature = "testing"),test))]
mod testusage {
#[test]
fn panic_without_testing_feature() {
panic!("Please use the feature testing when running tests.\n\nUse: cargo test --features testing\n\n");
}
}
Run Code Online (Sandbox Code Playgroud)
仅当通过为其添加防护来启用该功能时才编译实用程序:
#[cfg(feature = "testing")]
fn testing_utility() {
}
Run Code Online (Sandbox Code Playgroud)
无论它依赖多少个测试功能,这只会在每个包中添加一个功能,但缺点是需要特殊调用测试。
避免在任何 crate 范围的依赖声明中添加此功能。crate-0包括开发依赖性中的测试功能,crate-1即使对于发布模式下的构建目标,也对具有该功能的货物构建结果crate-1具有正常的依赖性。crate-0crate-0crate-1