我可以只为集成测试和/或基准测试公开对象吗? [英] Can I make an object public for integration tests and/or benchmarks only?

查看:20
本文介绍了我可以只为集成测试和/或基准测试公开对象吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As suggested by The Book, I have moved the integration tests in my crate to a tests directory. Some of those tests use functions that I don't want to export outside of the crate, though, and I am no longer able to use them in the integration test folder. I use them for non-test purposes too, so they need to compile outside of tests too. I tried using variants of pub(restricted), but I wasn't able to make it work. Ideally I'd like to have something like pub(tests).

目录树(相关位):

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

tests/parsing.rs:

tests/parsing.rs:

extern crate my_crate;

use my_crate::parser::foo;

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

长凳/parsing.rs:

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(); });
}

我目前的解决方法是使相关对象 public 并且在文档中不可见 (#[doc(hidden)]),但它没有传达适当的意图.我可以将对象公开以用于集成测试/基准测试吗?

My current workaround is to make the relevant objects public and invisible in the docs (#[doc(hidden)]), but it doesn't convey the proper intention. Can I make an object public only for integration test / benchmarking purposes?

推荐答案

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

One difference between integration tests and unit tests is that integration tests is supposed to test the "public API" of your crate only. Tests for internal functions is fine to keep together with the functions themselves in the src tree.

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

If you want to keep them a little separate, you can use a test submodule to the module containing the functions to test, as private parts are available to submodules.

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

If you still really want to have internal / unit tests in the tests in the tests directory, you can use a feature flag to enable public wrappers of internal functions to test (and mark the tests with the same feature flag). Something like this in the code:

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

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

Then in your test methods, you can import and call exposed_something. If the feature testable_privates is not defined, your tests will fail to compile. To solve that, use the feature flag to make the tests conditional as well;

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

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

Also, before doing that you need to define the feature in your Cargo.toml, like so:

[features]
testable_privates = []

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

(The empty array is to signify that the feature does not require any otherwise optional dependencies).

现在,如果你只运行cargo test,那么exposed_something 和test_something 都会被默默忽略,但是如果你运行cargo test --features testable_privates,它们将会被忽略编译和测试.

Now, if you just run cargo test, both exposed_something and test_something will just be silently ignored, but if you run cargo test --features testable_privates, they will be compiled and tested.

如你所见,这变得相当复杂,所以我真的认为从 tests 测试你的 crate 的公共方面是一个更好的主意,并将私有方法的测试保持在这些方法本身附近src.

As you see, this gets rather complicated, so I really think it is a better idea to just test public aspects of your crates from tests and keep tests of private methods close to those methods themselves in src.

这篇关于我可以只为集成测试和/或基准测试公开对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆