根据 The Book 的建议,我已将箱子中的集成测试移至 tests
目录。不过,其中一些测试使用了我不想导出到 crate 之外的函数,而且我无法再在集成测试文件夹中使用它们。我也将它们用于非测试目的,因此它们也需要在测试之外进行编译。我尝试使用 pub(restricted)
的变体,但我无法让它发挥作用。理想情况下,我想要像 pub(tests)
这样的东西。
目录树(相关位):
my_crate
|- src
|- parser.rs
|- tests
|- parsing.rs
|- benches
|- parsing.rs
测试/解析.rs:
extern crate my_crate;
use my_crate::parser::foo;
#[test]
fn temp() {
foo();
}
benches/parsing.rs:
#![feature(test)]
extern crate test;
extern crate my_crate;
use test::Bencher;
use my_crate::parser::foo;
#[bench]
fn temp(b: &mut Bencher) {
b.iter(|| { foo(); });
}
我目前的解决方法是使相关对象在文档中pub
许可和不可见(#[doc(hidden)]
),但它没有传达适当的意图。我可以仅将对象公开用于集成测试/基准测试目的吗?
最佳答案
集成测试和单元测试之间的一个区别是集成测试应该只测试你的 crate 的“公共(public) API”。内部函数的测试可以与 src
树中的函数本身保持在一起。
如果你想让它们稍微分开,你可以对包含要测试的函数的模块使用测试子模块,因为子模块可以使用私有(private)部分。
如果您仍然真的想在tests
目录中的测试中进行内部/单元测试,您可以使用功能标志启用内部函数的公共(public)包装器进行测试(并用相同的功能标志)。代码中是这样的:
#[cfg(feature = "testable_privates")]
pub fn exposed_something(args) {
something_private(args)
}
然后在您的测试方法中,您可以导入并调用exposed_something
。如果未定义特性 testable_privates
,您的测试将无法编译。要解决这个问题,请使用功能标志使测试也有条件;
#[cfg(feature = "testable_privates")]
#[test]
fn test_something() {
assert_eq!(exposed_something(my_args), expected_result)
}
此外,在执行此操作之前,您需要在 Cargo.toml
中定义该功能,如下所示:
[features]
testable_privates = []
(空数组表示该功能不需要任何其他可选依赖项)。
现在,如果您只运行 cargo test
,exposed_something 和 test_something 都将被静默忽略,但如果您运行 cargo test --features testable_privates
,它们将被忽略编译和测试。
如你所见,这变得相当复杂,所以我真的认为最好只从 tests
测试你的 crates 的公共(public)方面,并将私有(private)方法的测试保持在靠近这些方法本身的地方源代码
。
关于module - 我可以将对象公开用于集成测试和/或基准测试吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47698194/