问题描述
我的 crate-0 有 src/lib.rs
如下:
I have crate-0 that has src/lib.rs
as follows:
#[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 中定义的测试框架:
I also have crate-1 where I need the testing framework I defined in 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 时使用.
The code here is trivial and can be copy-pasted, but in reality I have complex test utilities which I want to use while testing crate-1.
我无法将测试实用程序分离到不同的 crate 中,因为我会得到循环依赖错误:test_utils
将依赖于 crate-0
create stuff 和 crate-0
将依赖 test_utils
进行测试).我实际上也不想这样做,因为还有更多的 crate,我想在依赖 crate 中使用它们的测试实用程序.
I cannot separate out the test utilities into a different crate as I would get cyclic dependency error: test_utils
would depend on crate-0
create stuff and crate-0
would depend on test_utils
for testing). Nor do I actually want to do this as there are further crates down the line whose testing utilities I would like to use in dependent crates.
推荐答案
权衡明显不同的两种解决方案:
Two solutions with sightly different trade-offs:
将您的测试实用程序而不是您的测试放入一个新的 crate crate-0-testutils
.使 crate-0
依赖于 crate-0-testutils
;crate-0-testutils
依赖于 crate-0
;crate-1
开发依赖于 crate-0-testutils
并依赖于 crate-0.
Put your test utilities but not your tests in a new crate crate-0-testutils
.Make crate-0
dev-depend on crate-0-testutils
; crate-0-testutils
depend on crate-0
; crate-1
dev-depend on crate-0-testutils
and depend on crate-0.
这不会创建循环依赖,因为开发依赖不会被传播.由于开发依赖性,您在 crate-0 中的测试仍然可以使用 crate-0-testutils 中的内容.
This does not create a circular dependency as the dev-dependencies do not get propagated. Because of the dev-dependency your tests in crate-0 can still use what is in crate-0-testutils.
如果您的所有创建都具有此类实用程序,这最多会使您的 lib crate 数量增加一倍.
This at most doubles the number of your lib crates if all your creates had such utilities.
在crate-0
的Cargo.toml
中创建一个不依赖任何东西的特征:
Create a feature in the Cargo.toml
ofcrate-0
that does not depend on anything:
[features]
testing = []
crate-1
中的一个依赖于上述内容:
And one in crate-1
that depends on the above:
testing = ["crate-0/testing"]
然后在未启用该功能时对每个板条箱进行第一次测试失败,以便更容易理解错误:
Then make the first tests on each of the crates fail when the feature is not enabled, to make for an easier to understand error:
#[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");
}
}
仅在通过为其添加保护而启用该功能时编译实用程序:
Only compile the utilities when the feature is enabled by adding a guard for it:
#[cfg(feature = "testing")]
fn testing_utility() {
}
这只会在每个 crate 中添加一个功能,而不管它依赖多少测试功能,但缺点是需要对测试进行特殊调用.
This only adds one feature in each crate regardless of how many testing features it depends on but has the downside of needing a special invocation of the tests.
避免在任何 crate 范围的依赖声明中添加此功能.在 crate-1
的 dev-dependency 中包含来自 crate-0
的测试功能,其中 crate-1
也有一个对 crate-1
的正常依赖即使在发布模式下,code>crate-0 也会生成具有该功能的货物构建 crate-0
,即使对于 crate-1
的构建目标也是如此.
Avoid adding this feature in any crate wide dependency declaration. Including the testing-feature from crate-0
in the dev-dependency of crate-1
where crate-1
also has a normal dependency on crate-0
results in cargo building crate-0
with that feature even for the build target of crate-1
even in release mode.
这篇关于我们可以在板条箱之间共享测试实用程序吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!