繁体   English   中英

如何将测试移动到 Rust 的 Cargo 二进制文件的单独文件中?

[英]How to move tests into a separate file for binaries in Rust's Cargo?

我使用 Cargo 创建了一个新的二进制文件:

cargo new my_binary --bin

my_binary/src/main.rs中的一个function可以用来测试:

fn function_from_main() {
    println!("Test OK");
}

#[test]
fn my_test() {
    function_from_main();
}

并且cargo test -- --nocapture按预期运行测试。

将此测试移至单独文件的最直接方法是什么(将function_from_main保留在my_binary/src/main.rs中)?

我试图这样做但不确定如何从单独的文件中调用function_from_main my_test

Rust 编程语言一章专门介绍测试,你应该阅读它以获得基本的理解。


将单元测试(允许访问代码内部的test )放入每个特定文件的test模块中是很常见的:

fn function_from_main() {
    println!("Test OK");
}

#[cfg(test)]
mod test {
    use super::*;
    
    #[test]
    fn my_test() {
        function_from_main();
    }
}

模块可以移动到新文件,尽管这对于单元测试模块来说并不常见:

主文件

fn function_from_main() {
    println!("Test OK");
}

#[cfg(test)]
mod test;

测试.rs

use super::*;

#[test]
fn my_test() {
    function_from_main();
}

有关文件和模块如何相互映射的详细信息,请参阅将模块分成不同的文件


单独文件中的测试更常见的情况是集成测试。 书中还有一个专门介绍板条箱外测试部分 这些类型的测试非常适合作为代码的使用者来执行代码

文档的该部分包括介绍性示例和描述性文本:

我们在项目目录的顶层创建一个测试目录,在src旁边。 Cargo 知道在这个目录中寻找集成测试文件。 然后我们可以在这个目录中创建任意数量的测试文件,Cargo 会将每个文件编译为一个单独的 crate。

让我们创建一个集成测试。 示例11-12 中的代码仍在src/lib.rs文件中,创建一个测试目录,创建一个名为tests/integration_test.rs的新文件,然后输入示例11-13 中的代码:

文件名:tests/integration_test.rs

 use adder; #[test] fn it_adds_two() { assert_eq!(4, adder::add_two(2)); }

示例 11-13:加法器箱中函数的集成测试

我们在代码顶部添加了use adder ,我们在单元测试中不需要它。 原因是 tests 目录中的每个测试都是一个单独的 crate,所以我们需要将我们的库放入每个 test crate 的范围内。

请注意,该函数被称为adder::add_two 关于 Rust 模块系统的更多细节可以在包、板条箱和模块章节中找到

由于这些测试像用户一样运行您的 crate,如果您想测试一个binary ,您应该执行 binary assert_cmd这样的crate可以帮助减少这种类型的测试的痛苦。

在其他情况下,您应该将大二进制文件分解为一个大库和一个小二进制文件。 然后,您可以为库的公共 API 编写集成测试。

另见:

如果你有一个模块foo.rs并且想要将你的单元测试放在一个名为foo_test.rs的文件中,你会发现这并不总是 Rust 寻找子模块的地方。

可以使用#[path]属性指定模块对应的文件位置:

#[cfg(test)]
#[path = "./foo_test.rs"]
mod foo_test;

这在博客文章Better location for unit tests in Rust 中进行了解释

你说得对; function_from_mainmain.rs之外是不可访问的。

您需要创建一个src/lib.rssrc/lib.rs移动要测试的函数。 然后你就可以使用extern crate my_binary; 来自您的测试模块,并使您的函数出现在my_binary命名空间下。

我确实相信您应该遵循阅读 Rust 书中测试章节的建议,但是,这仍然不能完全回答您的问题,如何分离测试文件和源文件

假设您有一个lib.rs源文件并想要一个test_lib.rs文件。 为此,您只需要:

在你的lib.rs

mod test_lib;

// rest of source

然后在你的test_lib.rs中:

#[cfg(test)]
use super::*;

#[test]
fn test1() {
    // test logic 
}

// more tests

然后,你和cargo test应该都很开心。

修饰*@mmai 的回答:

#[rustfmt::skip]
#[cfg(test)]
#[path = "./foo_test.rs"]
mod foo_test;

cargo fmt似乎对新测试文件的路径不满意。 如果有人有更好的解决方案,我会很高兴听到它,因为我希望cargo fmt也能格式化我的测试文件!

*抱歉:我添加这个只是作为对现有答案的评论,但我没有足够的声誉。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM