🎃个人专栏:
🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客
🐳Java基础:Java基础_IT闫的博客-CSDN博客
🐋c语言:c语言_IT闫的博客-CSDN博客
🐟MySQL:数据结构_IT闫的博客-CSDN博客
🐠数据结构:数据结构_IT闫的博客-CSDN博客
💎C++:C++_IT闫的博客-CSDN博客
🥽C51单片机:C51单片机(STC89C516)_IT闫的博客-CSDN博客
💻基于HTML5的网页设计及应用:基于HTML5的网页设计及应用_IT闫的博客-CSDN博客
🥏python:python_IT闫的博客-CSDN博客
🐠离散数学:离散数学_IT闫的博客-CSDN博客
🥽Linux:Linux_Y小夜的博客-CSDN博客
🚝Rust:Rust_Y小夜的博客-CSDN博客
欢迎收看,希望对大家有用!
目录
🎯单元测试
单元测试的目的是在与其他部分隔离的环境中测试每一个单元的代码,以便于快速而准确地验证某个单元的代码功能是否符合预期。单元测试与它们要测试的代码共同存放在位于 src 目录下相同的文件中。规范是在每个文件中创建包含测试函数的
tests
模块,并使用cfg(test)
标注模块。
🎃测试模块和#[cfg(test)]
测试模块的
#[cfg(test)]
注解告诉 Rust 只在执行cargo test
时才编译和运行测试代码,而在运行cargo build
时不这么做。这在只希望构建库的时候可以节省编译时间,并且因为它们并没有包含测试,所以能减少编译产生的文件的大小。与之对应的集成测试因为位于另一个文件夹,所以它们并不需要#[cfg(test)]
注解。然而单元测试位于与源码相同的文件中,所以你需要使用#[cfg(test)]
来指定它们不应该被包含进编译结果中。#[cfg(test)] mod tests { #[test] fn it_works() { let result = 2 + 2; assert_eq!(result, 4); } }
cfg
属性代表配置(configuration) ,它告诉 Rust,接下来的项,只有在给定特定配置选项时,才会被包含。在这种情况下,配置选项是test
,即 Rust 所提供的用于编译和运行测试的配置选项。通过使用cfg
属性,Cargo 只会在我们主动使用cargo test
运行测试时才编译测试代码。这包括测试模块中可能存在的帮助函数,以及标注为#[test]
的函数。
🎃测试私有函数
pub fn add_two(a: i32) -> i32 { internal_adder(a, 2) } fn internal_adder(a: i32, b: i32) -> i32 { a + b } #[cfg(test)] mod tests { use super::*; #[test] fn internal() { assert_eq!(4, internal_adder(2, 2)); } }
注意
internal_adder
函数并没有标记为pub
。测试也不过是 Rust 代码,同时tests
也仅仅是另一个模块。
🎯集成测试
在 Rust 中,集成测试对于你需要测试的库来说完全是外部的。同其他使用库的代码一样使用库文件,也就是说它们只能调用一部分库中的公有 API。集成测试的目的是测试库的多个部分能否一起正常工作。一些单独能正确运行的代码单元集成在一起也可能会出现问题,所以集成测试的覆盖率也是很重要的。
🎃tests目录
为了编写集成测试,需要在项目根目录创建一个 tests 目录,与 src 同级。Cargo 知道如何去寻找这个目录中的集成测试文件。接着可以随意在这个目录中创建任意多的测试文件,Cargo 会将每一个文件当作单独的 crate 来编译。
adder ├── Cargo.lock ├── Cargo.toml ├── src │ └── lib.rs └── tests └── integration_test.rs
use adder; #[test] fn it_adds_two() { assert_eq!(4, adder::add_two(2)); }
因为每一个
tests
目录中的测试文件都是完全独立的 crate,所以需要在每一个文件中导入库。为此与单元测试不同,我们需要在文件顶部添加use adder
。
🎃集成测试的子模块
为了不让
common
出现在测试输出中,我们将创建 tests/common/mod.rs ,而不是创建 tests/common.rs 。现在项目目录结构看起来像这样:├── Cargo.lock ├── Cargo.toml ├── src │ └── lib.rs └── tests ├── common │ └── mod.rs └── integration_test.rs
这样命名告诉 Rust 不要将
common
看作一个集成测试文件。将setup
函数代码移动到 tests/common/mod.rs 并删除 tests/common.rs 文件之后,测试输出中将不会出现这一部分。tests 目录中的子目录不会被作为单独的 crate 编译或作为一个测试结果部分出现在测试输出中。
🎃二进制create的集成测试
如果项目是二进制 crate 并且只包含 src/main.rs 而没有 src/lib.rs,这样就不可能在 tests 目录创建集成测试并使用
extern crate
导入 src/main.rs 中定义的函数。只有库 crate 才会向其他 crate 暴露了可供调用和使用的函数;二进制 crate 只意在单独运行。这就是许多 Rust 二进制项目使用一个简单的 src/main.rs 调用 src/lib.rs 中的逻辑的原因之一。因为通过这种结构,集成测试 就可以 通过
extern crate
测试库 crate 中的主要功能了,而如果这些重要的功能没有问题的话,src/main.rs 中的少量代码也就会正常工作且不需要测试。