Rust断言测试库claim的使用,高效验证代码逻辑和错误处理的断言工具

Rust断言测试库claim的使用,高效验证代码逻辑和错误处理的断言工具

介绍

claim是一个为Rust提供的补充断言宏库,它扩展了Rust标准库中缺失的断言功能。这个库提供了多种断言宏来帮助开发者更高效地验证代码逻辑和错误处理。

主要功能

  • 比较断言assert_ge, assert_gt, assert_le, 和 assert_lt
  • 模式匹配断言assert_matches
  • Result类型断言assert_ok, assert_err, 和 assert_ok_eq
  • Option类型断言assert_some, assert_none, 和 assert_some_eq
  • Poll类型断言assert_pending, assert_ready, assert_ready_ok, assert_ready_err, 和 assert_ready_eq

安装

将以下内容添加到你的Cargo.toml文件中,用于测试、示例和基准测试:

[dev-dependencies]
claim = "0.5"

使用示例

#[cfg(test)]
mod tests {
    use claim::*;
    
    #[test]
    fn test_comparison_assertions() {
        let a = 5;
        let b = 10;
        
        assert_ge!(b, a);  // 断言 b >= a
        assert_gt!(b, a);  // 断言 b > a
        assert_le!(a, b);  // 断言 a <= b
        assert_lt!(a, b);  // 断言 a < b
    }
    
    #[test]
    fn test_result_assertions() {
        let ok_result: Result<i32, &str> = Ok(42);
        let err_result: Result<i32, &str> = Err("error");
        
        assert_ok!(ok_result);  // 断言结果是Ok
        assert_ok_eq!(ok_result, 42);  // 断言结果是Ok且等于42
        assert_err!(err_result);  // 断言结果是Err
    }
    
    #[test]
    fn test_option_assertions() {
        let some_value: Option<i32> = Some(42);
        let none_value: Option<i32> = None;
        
        assert_some!(some_value);  // 断言是Some
        assert_some_eq!(some_value, 42);  // 断言是Some且等于42
        assert_none!(none_value);  // 断言是None
    }
    
    #[test]
    fn test_poll_assertions() {
        use std:: task::Poll;
        
        let ready_value: Poll<i32> = Poll::Ready(42);
        let pending_value: Poll<i32> = Poll::Pending;
        
        assert_ready!(ready_value);  // 断言是Ready
        assert_ready_eq!(ready_value, 42);  // 断言是Ready且等于42
        assert_pending!(pending_value);  // 断言是Pending
    }
}

完整示例demo

// 在Cargo.toml中添加:
// [dev-dependencies]
// claim = "0.5"

#[cfg(test)]
mod claim_demo {
    use claim::*;
    use std::task::Poll;
    
    #[test]
    fn demo_all_assertions() {
        // 比较断言
        assert_ge!(10, 5);  // 10 >= 5
        assert_gt!(10, 5);  // 10 > 5
        assert_le!(5, 10);  // 5 <= 10
        assert_lt!(5, 10);  // 5 < 10
        
        // 模式匹配断言
        let value = Some(42);
        assert_matches!(value, Some(x) if x == 42);  // 匹配Some(42)
        
        // Result类型断言
        let ok_result: Result<i32, &str> = Ok(42);
        let err_result: Result<i32, &str> = Err("error");
        
        assert_ok!(ok_result);  // 断言Ok
        assert_ok_eq!(ok_result, 42);  // 断言Ok且值为42
        assert_err!(err_result);  // 断言Err
        
        // Option类型断言
        let some_value: Option<i32> = Some(42);
        let none_value: Option<i32> = None;
        
        assert_some!(some_value);  // 断言Some
        assert_some_eq!(some_value, 42);  // 断言Some且值为42
        assert_none!(none_value);  // 断言None
        
        // Poll类型断言
        let ready_ok: Poll<Result<i32, &str>> = Poll::Ready(Ok(42));
        let ready_err: Poll<Result<i32, &str>> = Poll::Ready(Err("error"));
        let pending_value: Poll<i32> = Poll::Pending;
        
        assert_ready!(ready_ok);  // 断言Ready
        assert_ready_ok!(ready_ok);  // 断言Ready且是Ok
        assert_ready_ok_eq!(ready_ok, 42);  // 断言Ready且Ok值为42
        assert_ready_err!(ready_err);  // 断言Ready且是Err
        assert_pending!(pending_value);  // 断言Pending
    }
    
    // 测试失败案例
    #[test]
    #[should_panic]
    fn test_failing_assertions() {
        assert_ge!(5, 10);  // 这会失败,因为5不大于等于10
    }
}

许可证

本库采用Apache License 2.0或MIT许可证双重许可,你可以选择其中一种使用。


1 回复

Rust断言测试库claim的使用指南

claim是一个Rust断言测试库,提供了比标准库assert!更丰富的断言功能,特别适合验证代码逻辑和错误处理。

主要特性

  • 提供多种断言宏,覆盖常见测试场景
  • 错误信息更清晰明确
  • 支持OptionResult类型的专门断言
  • 支持异步测试断言

安装

Cargo.toml中添加依赖:

[dev-dependencies]
claim = "0.5"

基本使用方法

1. 标准断言

use claim::assert_ge;

#[test]
fn test_basic_assertions() {
    assert_ge!(5, 3);  // 断言5 >= 3
    assert_lt!(2, 4);  // 断言2 < 4
    assert_eq!(10, 10); // 断言10 == 10
}

2. Option类型断言

use claim::{assert_some, assert_none};

#[test]
fn test_option() {
    let some_value: Option<i32> = Some(42);
    assert_some!(some_value);  // 断言是Some
    
    let none_value: Option<i32> = None;
    assert_none!(none_value);  // 断言是None
    
    // 可以提取Some中的值
    let value = assert_some_eq!(some_value, 42);
    assert_eq!(value, 42);
}

3. Result类型断言

use claim::{assert_ok, assert_err};

#[test]
fn test_result() {
    let ok_result: Result<i32, &str> = Ok(42);
    assert_ok!(ok_result);  // 断言是Ok
    
    let err_result: Result<i32, &str> = Err("error");
    assert_err!(err_result);  // 断言是Err
    
    // 可以提取Ok中的值或Err中的错误
    let value = assert_ok_eq!(ok_result, 42);
    assert_eq!(value, 42);
    
    let error = assert_err_eq!(err_result, "error");
    assert_eq!(error, "error");
}

4. 异步测试支持

use claim::assert_ok_async;
use futures::future;

#[tokio::test]
async fn test_async() {
    let future = future::ready(Ok::<i32, &str>(42));
    assert_ok_async!(future).await;  // 异步断言Ok
    
    // 也可以断言值
    let value = assert_ok_eq_async!(future, 42).await;
    assert_eq!(value, 42);
}

5. 调试断言

claim还提供了调试版本的断言,只在调试构建中生效:

use claim::debug_assert_some;

fn some_function(opt: Option<i32>) {
    debug_assert_some!(opt);  // 只在debug构建中检查
    // 函数逻辑...
}

高级用法

自定义错误信息

#[test]
fn test_custom_message() {
    let result: Result<i32, &str> = Err("failure");
    assert_err!(result, "Expected an error but got {:?}", result);
}

模式匹配断言

#[test]
fn test_pattern_matching() {
    let result: Result<i32, String> = Err("error".to_string());
    assert_matches!(result, Err(e) if e == "error");
}

完整示例代码

// 测试模块
#[cfg(test)]
mod tests {
    use claim::{
        assert_ge, assert_lt, assert_eq,
        assert_some, assert_none, assert_some_eq,
        assert_ok, assert_err, assert_ok_eq, assert_err_eq,
        assert_ok_async, assert_ok_eq_async,
        debug_assert_some,
        assert_matches
    };
    use futures::future;

    // 1. 测试基础断言
    #[test]
    fn test_basic_assertions() {
        assert_ge!(5, 3);  // 5 >= 3
        assert_lt!(2, 4);  // 2 < 4
        assert_eq!(10, 10); // 10 == 10
    }

    // 2. 测试Option断言
    #[test]
    fn test_option_assertions() {
        let some_val = Some(42);
        assert_some!(some_val);
        
        let none_val: Option<i32> = None;
        assert_none!(none_val);
        
        let extracted = assert_some_eq!(some_val, 42);
        assert_eq!(extracted, 42);
    }

    // 3. 测试Result断言
    #[test]
    fn test_result_assertions() {
        let ok_result: Result<i32, &str> = Ok(42);
        assert_ok!(ok_result);
        
        let err_result: Result<i32, &str> = Err("error");
        assert_err!(err_result);
        
        let ok_value = assert_ok_eq!(ok_result, 42);
        assert_eq!(ok_value, 42);
        
        let err_value = assert_err_eq!(err_result, "error");
        assert_eq!(err_value, "error");
    }

    // 4. 测试异步断言
    #[tokio::test]
    async fn test_async_assertions() {
        let future = future::ready(Ok::<i32, &str>(42));
        assert_ok_async!(future).await;
        
        let value = assert_ok_eq_async!(future, 42).await;
        assert_eq!(value, 42);
    }

    // 5. 测试调试断言
    fn test_debug_assertion(opt: Option<i32>) -> i32 {
        debug_assert_some!(opt);
        opt.unwrap_or_default()
    }

    // 6. 测试自定义错误信息
    #[test]
    fn test_custom_error_message() {
        let result: Result<i32, &str> = Err("failure");
        assert_err!(result, "应该返回错误但实际上得到了: {:?}", result);
    }

    // 7. 测试模式匹配断言
    #[test]
    fn test_pattern_match_assertion() {
        let result: Result<i32, String> = Err("specific error".to_string());
        assert_matches!(result, Err(e) if e == "specific error");
    }
}

为什么使用claim而不是标准断言?

  1. 更清晰的错误信息
  2. 更专业的OptionResult处理
  3. 更丰富的断言类型
  4. 更好的异步测试支持
  5. 更符合Rust惯用法的API设计

claim库是Rust测试中一个强大的补充,特别适合需要精细控制断言和错误处理的场景。

回到顶部