#test-framework #assert #matching #fluent #test #hamcrest

dev galvanic-assert

一套基于匹配器的断言和期望,便于测试。支持检查数字、对象、枚举变体、集合、panic等属性。结构匹配允许您将匹配器集成到结构分解中,以减少代码重复。也可以轻松编写自己的匹配器进行断言。该包将成为电化学测试框架(开发中)的一部分。您还可以将其断言用于其他测试框架。适用于:稳定版、beta版和nightly版

12个版本

使用旧的Rust 2015

0.8.7 2018年1月21日
0.8.6 2017年9月2日
0.8.5 2017年7月29日
0.8.0 2017年3月18日

#259测试

Download history 605/week @ 2024-03-13 597/week @ 2024-03-20 579/week @ 2024-03-27 626/week @ 2024-04-03 651/week @ 2024-04-10 734/week @ 2024-04-17 773/week @ 2024-04-24 1064/week @ 2024-05-01 992/week @ 2024-05-08 441/week @ 2024-05-15 558/week @ 2024-05-22 491/week @ 2024-05-29 264/week @ 2024-06-05 198/week @ 2024-06-12 227/week @ 2024-06-19 192/week @ 2024-06-26

932 每月下载
用于 13 crates

Apache-2.0

78KB
892

Galvanic-assert:基于匹配器的断言和期望,便于测试

Build Status Documentation Crates.io

此crate提供基于匹配谓词的新断言宏(assert_that!expect_that!get_expectation_for!)来

  • 简化断言的编写
  • 使断言易于阅读和理解
  • 轻松扩展断言框架
  • 提供大量常见匹配器
  • galvanic-testgalvanic-mock集成
  • 与您喜欢的测试框架一起使用

该crate是galvanic的一部分——一个完整的Rust测试框架。该框架分为三个部分,因此您可以选择只使用所需的组件。

两分钟教程

每个断言都有以下形式:assert_that!(SOME_VALUE, MATCHES_SOMETHING);。要检查某个值是否满足某些匹配谓词,例如less_thancontains_in_orderis_variant!等,我们可以写如下代码来操作单个值

#[macro_use]
extern crate galvanic_assert;
use galvanic_assert::matchers::*;

#[test]
fn expression_should_compute_correct_value {
    assert_that!(&1+2, eq(3));
    // or more wordy ...
    assert_that!(&1+2, is(eq(3)));
}

或断言集合的属性...

use galvanic_assert::matchers::collection::*;
#[test]
fn expression_should_compute_correct_value {
    /// check for containment
    assert_that!(&vec![5,1,3,4,2], contains_in_any_order(vec![1,2,3,4,5]));
    // check for internal structure
    assert_that!(&vec![4,3,2,1], sorted_descending());
}

或变体的属性...

enum Variants {
    First(i32),
    Second { x: i32, y: i32 },
    Third
}

#[test]
fn should_be_the_correct_variant {
    let var = Second { x: 1, y: 2 };
    assert_that!(&var, is_variant!(Variants::Second));
}

如果您需要断言结构体或枚举的多个字段,可以使用结构匹配器...

enum Baz {
    Var1 { x: i32, y: f64 },
    Var2(i32, f64)
}

#[test]
fn expression_should_compute_correct_value {
    let var1 = Baz::Var1 { x: 12, y: 23.4 };
    assert_that!(&var1, has_structure!(Baz::Var1 {
        x: eq(12),
        y: lt(25.0)
    }));

    let var2 = Baz::Var2(12, 23.4);
    assert_that!(&var2, has_structure!(Baz::Var2 [eq(12), lt(25.0)] ));
}

也可以将多个匹配器组合起来创建更具有表达力的匹配器...

#[test]
fn expression_should_compute_correct_value {
    // invert the meaning of a matcher
    assert_that!(&1+2, not(greater_than(3)));
    // join several matchers conjunctively
    assert_that!(&1+2, all_of!(greater_than(0), less_than(5)));
    // join several matchers disjunctively
    assert_that!(&1+2, any_of!(greater_than(5), less_than(5)));
}

如果还不够,您可以编写自己的匹配器,可以是闭包...

#[test]
fn expression_should_compute_correct_value {
    assert_that!(&1+2, |x| {
        let builder = MatchResultBuilder::for_("odd");
        if x % 2 == 1 { builder.matched() } else { builder.failed_because("result is not odd") }
    });
}

或者如果足够简单,可以直接是表达式...

#[test]
fn expression_should_compute_correct_value {
    let val = 1 + 2;
    assert_that!(val % 2 == 1, otherwise "result is not odd");
}

如果更复杂,则实现表示匹配器状态的某个结构的Matcher特质。

断言积极的事情是好的,但有时我们期望某些事情会非常糟糕...

fn press_big_red_button() {
    panic!("shouldn't have done that ...");
}

#[test]
fn someting_should_go_wrong {
    assert_that!(press_big_red_button(), panics);
}

...除非它没有发生。

fn press_faulty_red_button() {
    return;
    panic!("shouldn't have done that ...");
}

#[test]
fn everything_is_fine {
    assert_that!(press_faulty_red_button(), does not panic);
}

再花两分钟来了解预期

断言会立即检查其正确性。这意味着后续的任何断言都不会执行,你可能会错过调试错误的重要信息。基本上,你想要尽可能多的信息来做到这一点。因此,引入了宏expect_that!get_expectation_for!

expect_that!宏和get_expectation_for!宏都像assert_that!一样以完全相同的方式声明一个预期,所以上一节中学到的任何内容仍然适用。条件仍然在指定的点上检查,但对结果的检查将推迟到稍后的时间。

expect_that!宏将结果的检查推迟到当前块的末尾。

{
    expect_that!(&1+1, equal_to(0));
    expect_that!(&1+1, less_than(4)); // is executed
}
expect_that!(1+1, panics); // is never executed as the first expectation panics at the end of the block

get_expectation_for!宏提供了更精细的控制。它返回一个Expectation对象,可以通过调用verify来验证...

let e1 = get_expectation_for!(&1+1, equal_to(0));
let e2 = get_expectation_for!(&1+1, less_than(4)); // is executed
e1.verify();
let e3 = get_expectation_for!(&1+1, panics); // is never executed as e1 panics

...或者,一旦对象超出作用域,将自动验证。

{
    let e1 = get_expectation_for!(&1+1, equal_to(0));
    let e2 = get_expectation_for!(&1+1, less_than(4)); // is executed
}
let e3 = get_expectation_for!(1+1, panics); // is never executed as e1 panics

没有更多要说的了——请查看文档和不断增长的匹配器列表。

记住...只有经过测试的代码才是快乐的代码!

贡献

非常欢迎贡献!(请阅读并同意许可证。)

包含的匹配器列表远未完成。如果你遇到一个有用的匹配器,请提交一个问题。在提交问题之前,请检查该类型本身是否已经有一个布尔谓词,例如,如Option::is_none()。这些已经由断言宏支持,并且只有在Matcher的错误信息实质上优于默认值时才应包括在内。如果缺少或损坏了某些内容,请提交问题(如果你愿意的话)发送拉取请求。

对于拉取请求,请确保包含测试用例以避免回归。应将针对Matchers的测试添加为集成测试,因为它们测试了与断言宏的集成。看看现有的那些!

无运行时依赖项