编写自动化测试

本文大部分内容翻译自:The Rust Programming Language

1. 如何编写测试

属性(attribute)是关于 Rust 代码片段的元数据,为了将一个函数变成测试函数,需要在fn行之前加上#[test]。当使用cargo test命令运行测试时,Rust会构建一个测试执行程序用来调用标记了test属性的函数,并报告每一个测试是通过还是失败。

当使用Cargo新建一个库项目时,它会自动为我们生成一个测试模块和一个测试函数。这有助于我们开始编写测试,因为这样每次开始新项目时不必去查找测试函数的具体结构和语法了。当然你也可以额外增加任意多的测试函数以及测试模块。

让我们创建一个新的库项目 adder:

1
2
3
$ cargo new adder --lib
Created library `adder` project
$ cd adder

adder库中src/lib.rs的内容如下:

1
2
3
4
5
6
7
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}

这是cargo new自动生成的测试模块和函数。

fn行之前的#[test]:这个属性表明这是一个测试函数,这样测试执行者就知道将其作为测试处理。因为也可以在tests模块中拥有非测试的函数来帮助我们建立通用场景或进行常见操作,所以需要使用#[test]属性标明哪些函数是测试。

函数体通过使用assert_eq!宏来断言 2 加 2 等于 4。一个典型的测试的格式,就是像这个例子中的断言一样。接下来运行就可以看到测试通过。

cargo test命令会运行项目中所有的测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cargo test
Compiling adder v0.1.0 (file:///projects/adder)
Finished test [unoptimized + debuginfo] target(s) in 0.57s
Running unittests (target/debug/deps/adder-92948b65e88960b4)

running 1 test
test tests::it_works ... ok

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

Doc-tests adder

running 0 tests

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

让我们增加另一个测试,不过这一次是一个会失败的测试。当测试函数中出现 panic 时测试就失败了。每一个测试都在一个新线程中运行,当主线程发现测试线程异常了,就将对应测试标记为失败。第九章讲到了最简单的造成 panic 的方法:调用 panic! 宏。写入新测试 another 后, src/lib.rs 现在看起来如示例 11-3 所示:

文件名: src/lib.rs

这段代码会 Panic!
#[cfg(test)]
mod tests {
#[test]
fn exploration() {
assert_eq!(2 + 2, 4);
}

#[test]
fn another() {
    panic!("Make this test fail");
}

}
示例 11-3:增加第二个因调用了 panic! 而失败的测试

再次 cargo test 运行测试。输出应该看起来像示例 11-4,它表明 exploration 测试通过了而 another 失败了:

$ cargo test
Compiling adder v0.1.0 (file:///projects/adder)
Finished test [unoptimized + debuginfo] target(s) in 0.72s
Running unittests (target/debug/deps/adder-92948b65e88960b4)

running 2 tests
test tests::another … FAILED
test tests::exploration … ok

failures:

—- tests::another stdout —-
thread ‘main’ panicked at ‘Make this test fail’, src/lib.rs:10:9
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

failures:
tests::another

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

error: test failed, to rerun pass ‘–lib’

2. 控制测试如何运行

3. 测试的组织结构

参考资料

[1] 编写自动化测试:https://kaisery.github.io/trpl-zh-cn/ch11-00-testing.html