Appearance
Rust 测试
测试是保证代码质量的重要手段,Rust 提供了强大的测试支持。本章节将介绍 Rust 中的测试方法。
测试基础
单元测试
单元测试通常放在 src 目录中,与被测试的代码放在同一个文件中:
rust
// src/lib.rs
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5);
assert_eq!(add(-1, 1), 0);
assert_eq!(add(0, 0), 0);
}
}集成测试
集成测试放在 tests 目录中:
src/
└── lib.rs
tests/
└── integration_test.rsrust
// tests/integration_test.rs
use my_crate::add;
#[test]
fn test_add_integration() {
assert_eq!(add(2, 3), 5);
assert_eq!(add(-1, 1), 0);
assert_eq!(add(0, 0), 0);
}运行测试
运行所有测试
bash
cargo test运行特定测试
bash
cargo test test_add运行特定模块的测试
bash
cargo test tests::显示测试输出
bash
cargo test -- --nocapture测试断言
assert!
assert! 宏用于断言一个条件为真:
rust
#[test]
fn test_assert() {
let value = true;
assert!(value);
}assert_eq! 和 assert_ne!
assert_eq! 宏用于断言两个值相等,assert_ne! 宏用于断言两个值不相等:
rust
#[test]
fn test_assert_eq() {
assert_eq!(2 + 2, 4);
assert_ne!(2 + 2, 5);
}assert!(with message)
可以为断言添加自定义消息:
rust
#[test]
fn test_with_message() {
let result = 2 + 2;
assert_eq!(result, 4, "2 + 2 should equal 4, but got {}", result);
}测试失败
预期失败的测试
使用 #[should_panic] 属性标记预期会失败的测试:
rust
#[test]
#[should_panic]
fn test_panic() {
panic!("This test should panic");
}测试结果
测试函数可以返回 Result<(), E> 类型:
rust
#[test]
fn test_result() -> Result<(), String> {
if 2 + 2 == 4 {
Ok(())
} else {
Err(String::from("2 + 2 should equal 4"))
}
}测试组织
测试模块
使用模块组织测试:
rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5);
}
#[test]
fn test_subtract() {
assert_eq!(subtract(5, 3), 2);
}
}测试工具函数
在测试模块中添加工具函数:
rust
#[cfg(test)]
mod tests {
use super::*;
fn setup() {
// 测试前的设置
}
#[test]
fn test_add() {
setup();
assert_eq!(add(2, 3), 5);
}
}模拟和依赖注入
使用 mockall 库
toml
[dependencies]
mockall = "0.11"rust
// src/lib.rs
pub trait Database {
fn get_user(&self, id: u32) -> Option<String>;
}
pub fn get_username(db: &dyn Database, id: u32) -> String {
db.get_user(id).unwrap_or_else(|| "Unknown".to_string())
}
#[cfg(test)]
mod tests {
use super::*;
use mockall::mock;
mock! {
pub Database {
fn get_user(&self, id: u32) -> Option<String>;
}
}
#[test]
fn test_get_username() {
let mut mock_db = MockDatabase::new();
mock_db.expect_get_user()
.with(eq(1))
.returning(|_| Some("Alice".to_string()));
assert_eq!(get_username(&mock_db, 1), "Alice");
}
}总结
- 单元测试:放在
src目录中,与被测试的代码放在同一个文件中 - 集成测试:放在
tests目录中 - 运行测试:使用
cargo test命令 - 测试断言:
assert!、assert_eq!、assert_ne! - 测试失败:
#[should_panic]和Result<(), E> - 测试组织:使用模块组织测试
- 模拟和依赖注入:使用
mockall库
测试是保证代码质量的重要手段,Rust 提供了强大的测试支持。通过本章节的学习,你应该已经掌握了 Rust 中的测试方法。