Rust 中的测试函数是用来验证非测试代码是否按照期望的方式运行的。测试函数体通常执行如下三种操作:
- 设置任何所需的数据或状态
- 运行需要测试的代码
- 断言其结果是我们所期望的
测试函数剖析
Rust 测试是带有 test 属性注解的函数。
新建 lib crate
测试$ cargo new adder --libCreated library `adder` project$ cd adder
#[cfg(test)]mod tests {#[test]fn it_works() {assert_eq!(2 + 2, 4);}}
使用 assert! 宏来检查结果
assert! 宏由标准库提供,对 boolean 条件的测试非常有用使用 assert_eq! 和 assert_ne! 宏来测试相等
```rust pub fn add_two(a: i32) -> i32 { a + 2 }
[cfg(test)]
mod tests { use super::*;
#[test]fn it_adds_two() {assert_eq!(4, add_two(2));}
}
需要注意的是,在一些语言和测试框架中,断言两个值相等的函数的参数叫做 expected 和 actual,而且指定参数的顺序是很关键的。然而在 Rust 中,他们则叫做 left 和 right,同时**指定期望的值和被测试代码产生的值的顺序并不重要**。<a name="bkhE2"></a>## 自定义失败信息为测试函数增加一个自定义失败信息参数:带占位符的格式字符串,以及 greeting 函数的值:```rustpub fn greeting(name: &str) -> String {String::from("Hello!")}#[cfg(test)]mod tests {use super::*;#[test]fn greeting_contains_name() {let result = greeting("Carol");assert!(result.contains("Carol"),"Greeting did not contain name, value was `{}`",result);}}
$ cargo testCompiling greeter v0.1.0 (file:///projects/greeter)Finished test [unoptimized + debuginfo] target(s) in 0.93sRunning unittests (target/debug/deps/greeter-170b942eb5bf5e3a)running 1 testtest tests::greeting_contains_name ... FAILEDfailures:---- tests::greeting_contains_name stdout ----thread 'main' panicked at 'Greeting did not contain name, value was `Hello!`', src/lib.rs:12:9note: run with `RUST_BACKTRACE=1` environment variable to display a backtracefailures:tests::greeting_contains_nametest result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00serror: test failed, to rerun pass '--lib'
使用 should_panic 检查 panic
pub struct Guess {value: i32,}// --snip--impl Guess {pub fn new(value: i32) -> Guess {if value < 1 {panic!("Guess value must be greater than or equal to 1, got {}.",value);} else if value > 100 {panic!("Guess value must be less than or equal to 100, got {}.",value);}Guess { value }}}#[cfg(test)]mod tests {use super::*;#[test]#[should_panic(expected = "Guess value must be less than or equal to 100")]fn greater_than_100() {Guess::new(200);}}
将 Result 用于测试
#[cfg(test)]mod tests {#[test]fn it_works() -> Result<(), String> {if 2 + 2 == 4 {Ok(())} else {Err(String::from("two plus two does not equal four"))}}}
为了断言一个操作返回 Err 成员,不要使用对 Resultassert!(value.is_err())。
