我可以只为集成测试和/或基准测试公开对象吗?

lje*_*drz 6 integration-testing module rust rust-cargo

正如The Book所建议的那样,我已将板条箱中的集成测试移动到一个tests目录中。但是,其中一些测试使用了我不想导出到 crate 之外的函数,而且我无法再在集成测试文件夹中使用它们。我也将它们用于非测试目的,因此它们也需要在测试之外进行编译。我尝试使用 的变体pub(restricted),但无法使其工作。理想情况下,我想要像pub(tests).

目录树(相关位):

my_crate
|- src
   |- parser.rs
|- tests
   |- parsing.rs
|- benches
   |- parsing.rs
Run Code Online (Sandbox Code Playgroud)

测试/解析.rs:

extern crate my_crate;

use my_crate::parser::foo;

#[test]
fn temp() {
    foo();
}
Run Code Online (Sandbox Code Playgroud)

长凳/解析.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(); });
}
Run Code Online (Sandbox Code Playgroud)

我目前的解决方法是pub在文档 ( #[doc(hidden)])中使相关对象保持可见和不可见,但这并没有传达正确的意图。我可以出于集成测试/基准测试的目的公开对象吗?

Ras*_*Kaj 5

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

如果您想让它们稍微分开,您可以将测试子模块用于包含要测试的功能的模块,因为子模块可以使用私有部分。

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

#[cfg(feature = "testable_privates")]
pub fn exposed_something(args) {
    something_private(args)
}
Run Code Online (Sandbox Code Playgroud)

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

#[cfg(feature = "testable_privates")]
#[test]
fn test_something() {
    assert_eq!(exposed_something(my_args), expected_result)
}
Run Code Online (Sandbox Code Playgroud)

此外,在此之前,您需要在您的 中定义该功能Cargo.toml,如下所示:

[features]
testable_privates = []
Run Code Online (Sandbox Code Playgroud)

(空数组表示该功能不需要任何其他可选的依赖项)。

现在,如果你只运行cargo test,暴露的东西和测试的东西都会被默默地忽略,但如果你运行cargo test --features testable_privates,它们将被编译和测试。

正如你看到的,这得到比较复杂,所以我真的认为这是你的箱子从刚刚测试公众方面一个更好的主意tests,并保持私有方法测试接近这些方法自己src