我是否可以将对象公开用于集成测试和/或基准测试?

时间:2017-12-07 15:16:03

标签: module rust integration-testing rust-cargo

正如The Book所建议的那样,我已将我的包中的集成测试移至tests目录。其中一些测试使用的功能我不想在箱子外面导出,但我不再能够在集成测试文件夹中使用它们。我也将它们用于非测试目的,所以他们也需要在测试之外进行编译。我尝试使用pub(restricted)的变体,但我无法使其工作。理想情况下,我想要pub(tests)

目录树(相关位):

my_crate
|- src
   |- parser.rs
|- tests
   |- parsing.rs
|- benches
   |- parsing.rs

测试/ parsing.rs:

extern crate my_crate;

use my_crate::parser::foo;

#[test]
fn temp() {
    foo();
}

长凳/ 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)]不可见,但它没有传达正确的意图。我可以将对象公开用于集成测试/基准测试吗?

2 个答案:

答案 0 :(得分:1)

集成测试和单元测试之间的一个区别是集成测试应该只测试您的包的“公共API”。内部函数的测试可以与src树中的函数本身保持一致。

如果你想让它们稍微分开,你可以使用一个测试子模块来包含要测试的函数的模块,因为子模块可以使用私有部分。

如果您仍然希望在tests目录中的测试中进行内部/单元测试,则可以使用功能标志来启用内部函数的公共包装器进行测试(并使用相同的功能标记测试旗)。代码中有这样的东西:

#[cfg(feature = "testable_privates")]
pub fn exposed_something(args) {
    something_private(args)
}

然后在您的测试方法中,您可以导入并调用exposed_something。如果未定义功能testable_privates,则无法编译测试。要解决这个问题,请使用feature标志使测试成为条件;

#[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测试您的包装箱的公共方面并在{{1}中保持私有方法的测试接近这些方法本身是一个更好的主意。 }}

答案 1 :(得分:0)

您可以通过添加仅在测试时存在且重新导出所需符号的公共模块来实现。类似的东西:

#[cfg(test)]
pub mod testing_parser {
    pub use parser::foo;
}

然后在您的测试中use my_crate::testing_parser::foo