Rust断言库assertor的使用:高效测试与验证代码逻辑的必备工具
Rust断言库assertor的使用:高效测试与验证代码逻辑的必备工具
Assertor是一个使测试断言和失败信息更易读的Rust库。它深受Java Truth在API设计和错误信息方面的启发,但这是一个完全独立的项目。
免责声明
这不是Google的官方产品,只是Google拥有的代码。⚠ API尚未完全稳定,可能在1.0版本之前会有变化。
示例
use assertor::*;
#[test]
fn test_it() {
assert_that!("foobarbaz").contains("bar");
assert_that!("foobarbaz").ends_with("baz");
assert_that!(0.5).with_abs_tol(0.2).is_approx_equal_to(0.6);
assert_that!(vec!["a", "b"]).contains("a");
assert_that!(vec!["a", "b"]).has_length(2);
assert_that!("foobarbaz").ends_with("baz");
assert_that!(0.5).with_abs_tol(0.2).is_approx_equal_to(0.6);
assert_that!(vec!["a", "b"]).contains("a");
assert_that!(vec!["a", "b"]).has_length(2);
assert_that!(vec!["a", "b"]).contains_exactly(vec!["a", "b"]);
assert_that!(Option::Some("Foo")).has_value("Foo");
}
完整示例demo
// 引入assertor库
use assertor::*;
// 测试字符串操作
#[test]
fn test_string_assertions() {
// 检查字符串包含
assert_that!("hello world").contains("world");
// 检查字符串结尾
assert_that!("foo bar").ends_with("bar");
}
// 测试数值操作
#[test]
fn test_numeric_assertions() {
// 近似相等检查
assert_that!(1.0).with_abs_tol(0.1).is_approx_equal_to(1.05);
}
// 测试集合操作
#[test]
fn test_collection_assertions() {
let vec = vec![1, 2, 3];
// 检查集合长度
assert_that!(vec).has_length(3);
// 检查集合包含元素
assert_that!(vec).contains(2);
}
// 测试Option操作
#[test]
fn test_option_assertions() {
// 检查Some值
assert_that!(Some("value")).has_value("value");
// 检查None
assert_that!(Option::<i32>::None).is_none();
}
// 测试anyhow错误(需要启用anyhow特性)
#[cfg(feature = "anyhow")]
#[test]
fn test_anyhow_assertions() {
use anyhow::anyhow;
fn failing_function() -> anyhow::Result<()> {
Err(anyhow!("operation failed"))
}
assert_that!(failing_function())
.err()
.has_message("operation failed");
}
特性想法
- [ ] 颜色/加粗
- [ ] 更好的diff: vec
- [ ] 更好的diff: set
- [ ] 更好的diff: HashMap
安装
在项目目录中运行以下Cargo命令:
cargo add assertor
或者在Cargo.toml中添加:
assertor = "0.0.4"
要使用anyhow功能,请添加:
assertor = { version = "0.0.4", features = ["anyhow"] }
1 回复
Rust断言库assertor的使用:高效测试与验证代码逻辑的必备工具
assertor
是Rust中一个强大的断言库,它提供了丰富的断言方法,可以帮助开发者更高效地编写测试和验证代码逻辑。相比标准库中的assert!
宏,assertor
提供了更详细的错误信息和更灵活的断言方式。
安装
在Cargo.toml
中添加依赖:
[dependencies]
assertor = "0.8"
基本使用方法
1. 基本断言
use assertor::*;
#[test]
fn test_basic_assertions() {
assert_that!(true).is_true();
assert_that!(false).is_false();
assert_that!(10).is_equal_to(10);
assert_that!(10).is_not_equal_to(20);
}
2. 数值比较
#[test]
fn test_number_comparisons() {
let value = 42;
assert_that!(value).is_greater_than(30);
assert_that!(value).is_greater_than_or_equal_to(42);
assert_that!(value).is_less_than(50);
assert_that!(value).is_less_than_or_equal_to(42);
// 范围检查
assert_that!(value).is_between(40, 45);
}
3. 字符串断言
#[test]
fn test_string_assertions() {
let message = "Hello, Rust!";
assert_that!(message).is_equal_to("Hello, Rust!");
assert_极速!");
assert_that!(message).contains("Rust");
assert_that!(message).starts_with("Hello");
assert_that!(message).ends_with("!");
assert_that!(message).has_length(12);
}
4. 集合断言
#[test]
fn test_collection_assertions() {
let numbers = vec![1, 2, 3, 4, 5];
assert_that!(numbers).has_length(5);
assert_that!(numbers).contains(3);
assert_that!(numbers).does_not_contain(10);
assert_that!(numbers).contains_all_of(&[2, 4]);
assert_that!(numbers).contains_exactly(&[1, 2, 3, 4, 5]);
}
5. Option和Result断言
#[test]
fn test_option_result_assertions() {
let some_value: Option<i32> = Some(42);
let none_value: Option<i32> = None;
assert_that!(some_value).is_some();
assert_that!(some_value).is_some_and(|x| *x == 42);
assert_that!(none_value).is_none();
let ok_result: Result<i32, &str> = Ok(42);
let err_result: Result<i32, &str> = Err("error");
assert_that!(ok_result).is_ok();
assert_that!(ok_result).is_ok_and(|x| *x == 42);
assert_that!(err_result).is_err();
assert_that!(err_result).is_err_and(|x| *x == "error");
}
6. 浮点数比较(考虑浮点精度)
#[test]
fn test_float_comparisons() {
let pi = 3.14159265359;
// 默认精度比较
assert_that!(pi).is_close_to(3.14, 0.01);
// 自定义精度比较
assert_that!(pi).is_close_to(3.1416, 0.0001);
}
7. 布尔表达式断言
#[test]
fn test_boolean_conditions() {
let x = 10;
let y = 20;
assert_that!(x > 5 && y < 30).is_true();
assert_that!(x == y).is_false();
}
高级功能
1. 自定义错误信息
#[test]
fn test_with_custom_message() {
let value = 42;
assert_that!(value)
.with_message("Value should be between 40 and 50")
.is_between(40, 50);
}
2. 链式调用
#[test]
fn test_chained_assertions() {
let name = "Rust";
assert_that!(name)
.has_length(4)
.starts_with("R")
.ends_with("t")
.contains("us");
}
3. 异步测试支持
#[tokio::test]
async fn test_async_code() {
let result = some_async_function().await;
assert_that!(result).is_ok();
}
完整示例代码
下面是一个综合使用assertor的完整测试示例:
use assertor::*;
// 测试模块
#[cfg(test)]
mod tests {
use super::*;
// 测试基本断言
#[test]
fn test_integrated_assertions() {
// 测试数值
let age = 25;
assert_that!(age)
.is_greater_than(18)
.is_less_than(60)
.is_equal_to(25);
// 测试字符串
let username = "rustacean";
assert_that!(username)
.has_length(9)
.starts_with("rust")
.contains("ace")
.is_equal_to("rustacean");
// 测试集合
let languages = vec!["Rust", "Go", "Python"];
assert_that!(languages)
.has_length(3)
.contains("Rust")
.does_not_contain("Java")
.contains_all_of(&["Go", "Python"]);
// 测试Option
let some_value: Option<&str> = Some("hello");
assert_that!(some_value)
.is_some()
.is_some_and(|x| *x == "hello");
// 测试Result
let result: Result<i32, &str> = Ok(100);
assert_that!(result)
.is_ok()
.is_ok_and(|x| *x == 100);
}
// 测试自定义错误信息
#[test]
fn test_custom_error_message() {
let score = 85;
assert_that!(score)
.with_message("Score should be between 80 and 90")
.is_between(80, 90);
}
// 异步测试示例
#[tokio::test]
async fn test_async_operation() {
async fn fetch_data() -> Result<String, &'static str> {
Ok("data".to_string())
}
let result = fetch_data().await;
assert_that!(result)
.is_ok()
.is_ok_and(|x| *x == "data");
}
}
为什么选择assertor
- 丰富的断言方法:提供比标准库更全面的断言选项
- 清晰的错误信息:失败时提供详细的错误描述,便于调试
- 链式调用:支持流畅的API设计,使测试代码更易读
- 类型安全:充分利用Rust的类型系统,减少运行时错误
- 活跃维护:定期更新,与Rust生态系统保持同步
assertor是Rust测试工具链中的强大补充,特别适合需要编写大量测试或复杂断言的项目。通过其丰富的API,可以显著提高测试代码的可读性和维护性。