柚子快报激活码778899分享:Rust个人学习之单元测试

http://yzkb.51969.com/

基础标记说明

Rust 是具备内嵌单元测试模块的。在 Rust 中,可以通过在源代码文件的顶部使用 #[test] 属性来标记一个函数作为测试函数。通常,这些测试函数位于与它们测试的源代码相同的文件中,但位于 mod tests 模块中。这是一个常用做法。 另外还有一个标记属性。#[cfg(test)] 是一个条件编译属性,它允许你编写只在测试构建中编译的代码。这对于定义只在测试时需要的辅助函数、类型或模块特别有用,从而避免在生产代码中引入不必要的开销或依赖。 创建一个测试代码:

fn im_true() -> bool { true

}

fn is_false() -> bool {

false

}

fn is_num_three() -> u32 {

3

}

fn is_string() -> String {

String::from("hello")

}

接下来测试函数 is_false 的返回是否为布尔值:否,需要先建立一个测试模块,然后建立一个测试函数

#[cfg(test)] mod test {

use crate::is_false;

#[test]

// check if is_false return false

fn check_bool_false() {

let f = is_false();

assert!(!f, "is not false");

}

#[test]

// check if return true

fn check_bool_true() {

let f = is_false();

assert!(f, "is not true");

}

}

上面的代码中建立了一个名字为 test 的测试模块,由于标记了#[cfg (test)]标签,所以在执行 cargo build 时是不会执行编译的,只有在执行 cargo test 时会编译执行。另外建立了两个单元测试内容:check_bool_false, check_bool_true,两个函数都用#[test]进行了标记。当执行 cargo test 时会看到两个测试项的结果。上述代码比较简单,应该是一个成功一个失败:

#cargo test

......

running 2 tests

test test::check_bool_false ... ok

test test::check_bool_true ... FAILED

failures:

---- test::check_bool_true stdout ----

thread 'test::check_bool_true' panicked at src/main.rs:37:9:

is not true

note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

failures:

test::check_bool_true

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass `--bin unitestlearn`

成功的单元测试会描述为 ok,而失败的会使用:FAILED 标记进行提示。同时会有标准输出以及总结哪些测试用例失败的描述。

断言

上述代码中有个关键字 assert!,这个关键字是检查给定的布尔表达式是否为真。如果为假,则测试失败。类似的关键字还有很多

关键字说明assert!检查给定的布尔表达式是否为真。如果为假,则测试失败。assert_eq!检查两个表达式是否相等。如果不等,则测试失败assert_ne!检查两个表达式是否不相等。如果相等,则测试失败Assert_debug_snapshot!用于比较当前代码的调试输出是否与先前存储的快照匹配,这有助于在重构代码时确保其行为未改变 (依赖 insta )

以下是一些案例

#[test] ----- 布尔值检查

// check if return true

fn check_bool_true() {

let f = im_true();

assert!(f, "is not true");

}

#[test] ---- 数字相等检查

fn check_equal_num() {

assert_eq!(2,2);

}

#[test] ----- 数字不等检查

fn check_ne_num() {

assert_ne!(3,2);

}

#[test] ----- 快照检查

fn check_snapshot() {

let mut settings = insta::Settings::clone_current();

settings.set_snapshot_path("../test/snapshot/");

settings.bind(|| {

let name = "helloworld";

insta::assert_debug_snapshot!(name);

});

}

快照检查需要多说一下,写快照检查时需要引入一个依赖,所以在 Cargo. Toml 中需要增加如下内容

[dependencies]

insta = "1.38.0"

在项目目录下创建一个 test/snapshot 目录,该目录将作为快照存储的目录,代码中采用 settings.set_snapshot_path 进行设置,settings. Bind 中设置测试流程,第一次执行时测试用例会失败,并自动在快照目录下生成一个快照文件,如上面的用例会生成一个:unitestlearn__test__check_snapshot.snap. New 的文件,生成后将该文件 new 的后缀去掉后保存就作为一个快照保存即可。

声明式宏

在 Rust 中可以通过 macro_rules!进行声明式宏的定义。能够减少重复代码的编写,简化代码,大大提高可读性和编码效率。 以下面为例:

macro_rules! snapshot_test {

($testname:ident, $txtcontent:literal) => {

#[test]

fn $testname() {

let mut settings = insta::Settings::clone_current();

settings.set_snapshot_path("../test/snapshot/");

settings.bind(|| {

let name = $txtcontent;

insta::assert_debug_snapshot!(name);

});

}

}

}

snapshot_test!(a_check, "a_check");

snapshot_test!(b_check, "b_check");

snapshot_test!(c_check, "c_check");

类似这种及其相似的代码就可以使用宏定义的方式快速实现。Macro_rules 的格式为

macro_rules! [宏定义名称] {

() => {}

// 其中括号为入参,大括号为函数体

}

针对宏定义的参数类型有以下几种

类型说明ident标识符,如变量名或函数名。block代码块,包括 { ... } 内的所有内容。stmt语句,如赋值或函数调用。expr表达式,可以求值为某个值的代码片段。pat模式,用于匹配值或解构数据。ty类型表达式,如 int 或 Vec。lifetime生命周期标注,如 'a。literal字面量,如字符串、整数或浮点数字面量。path路径,用于引用模块、类型或值。meta元项,如属性(attributes)。tt令牌树(token tree),可以包含任何有效的 Rust 令牌。item项,可以是一个函数、结构体定义等。vis可见性修饰符,如 pub 或 priv。

柚子快报激活码778899分享:Rust个人学习之单元测试

http://yzkb.51969.com/

精彩链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。