我的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()); }
}
我还有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()); }
}
这里的代码很简单,可以复制粘贴,但实际上我有一些复杂的测试工具,我想在测试crate-1时使用它。
我无法将测试实用程序分离到不同的包中,因为我会得到循环依赖性错误:test_utils
将取决于crate-0
创建内容而crate-0
将取决于{{1} } 用于检测)。我实际上也不想这样做,因为还有更多的板条箱,我想在依赖板条箱中使用它的测试工具。
答案 0 :(得分:2)
两种解决方案有着截然不同的权衡:
将测试实用程序而不是测试放在新的包crate-0-testutils
中。
让crate-0
取决于crate-0-testutils
; crate-0-testutils
取决于crate-0
; crate-1
dev-depend依赖crate-0-testutils
并依赖于crate-0。
这不会创建循环依赖关系,因为dev依赖关系不会传播。由于dev依赖,你在crate-0中的测试仍然可以使用crate-0-testutils中的内容。
如果您创建的所有内容都具有此类实用程序,则最多可将您的lib crate数量增加一倍。
在Cargo.toml
crate-0
中创建一个不依赖于任何内容的功能:
[features]
testing = []
crate-1
中的一个取决于上述内容:
testing = ["crate-0/testing"]
然后在未启用该功能时对每个包装箱进行第一次测试失败,以便更容易理解错误:
#[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");
}
}
仅在通过为其添加防护功能启用该功能时编译实用程序:
#[cfg(feature = "testing")]
fn testing_utility() {
}
这只会在每个包中添加一个功能,无论它依赖多少测试功能,但缺点是需要特殊的测试调用。
避免在任何crate wide依赖声明中添加此功能。将crate-0
中的测试功能包含在crate-1
的开发依赖项中,其中crate-1
也与crate-0
具有正常的依赖关系,从而导致货物构建crate-0
即使在发布模式下,即使对于crate-1
的构建目标也具有功能。