Rust学习笔记9 测试与评测

bradyjoestar · · 665 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

github地址:https://github.com/bradyjoestar/rustnotes
pdf下载链接:https://github.com/bradyjoestar/rustnotes/blob/master/Rust%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0.pdf
参考:
https://rustcc.gitbooks.io/rustprimer/content/ 《RustPrimer》
https://kaisery.github.io/trpl-zh-cn/ 《Rust程序设计语言-简体中文版》

第九章 测试与评测

在rust中内部构建了测试和评测模块,虽然目前bench模块仍然在nightly channel。

需要手动将rust切换到nightly版本,通过以下命令:

rustup default nightly

作为软件工程质量保障体系的重要一环,测试是应该引起我们充分注意并重视的事情。前面说过,Rust 语言的设计集成了最近十多年中总结出来的大量最佳工程实践,而对测试的原生集成也正体现了这一点。很大程度借鉴了golang的部分内容。
Rust 的测试特性按精细度划分,分为 3 个层次:
1.函数级;主要通过#[test] 标识
2.模块级;主要通过#[cfg(test)]标志。
3.工程级;例如黑盒测试,放于test目录下。
另外,Rust 还支持对文档进行测试。
一个项目中路径如下:


image.png

之前提到过的Cargo.toml补充:
cargo.toml和cargo.lock文件总是位于项目根目录下。
源代码位于src目录下。
默认的库入口文件是src/lib.rs。
默认的可执行程序入口文件是src/main.rs。
其他可选的可执行文件位于src/bin/*.rs(这里每一个rs文件均对应一个可执行文件)。
外部测试源代码文件位于tests目录下。
示例程序源代码文件位于examples。
基准测试源代码文件位于benches目录下。

9.1 函数级测试

当我们创建一个空的库项目时,打开src/lib.rs文件,可以看到如下代码:

#[test]
fn it_works() {
    // do test work
}

Rust 中,只需要在一个函数的上面,加上 #[test] 就标明这是一个测试用的函数。
有了这个属性之后,在使用cargo build编译时,就会忽略这些函数。使用 cargo test 可以运行这些函数。类似于如下效果:

$ cargo test
   Compiling adder v0.0.1 (file:///home/you/projects/adder)
     Running target/adder-91b3e234d4ed382a

running 1 test
test it_works ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

   Doc-tests adder

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

此外,可以使用的属性还有:

[ignore]

[should_panic]

9.2 模块级测试

有时,我们会组织一批测试用例,这时,模块化的组织结构就有助于建立结构性的测试体系。Rust 中,可以类似如下写法:

pub fn add_two(a: i32) -> i32 {
    a + 2
}

#[cfg(test)]
mod tests {
    use super::add_two;

    #[test]
    fn it_works() {
        assert_eq!(4, add_two(2));
    }
}

也即在 mod 的上面写上 #[cfg(test)] ,表明这个模块是个测试模块。一个测试模块中,可以包含若干测试函数,测试模块中还可以继续包含测试模块,即模块的嵌套。
如此,就形式了结构化的测试体系,甚是方便。

9.3工程级测试(黑盒集成测试)

函数级和模块级的测试,代码是与要测试的模块(编译单元)写在相同的文件中,一般做的是白盒测试。工程的测试,一般做的就是黑盒集成测试了。

我们看上图截图工程的目录,在这个目录下,有一个 tests 文件夹。

extern crate rusttest;
#[test]
fn block_box_test() {
    assert_eq!(4, rusttest::add_two(2));
}

这里,比如,我们 src 中,写了一个库,提供了一个 add_two 函数,现在进行集成测试。
首先,用 extern crate 的方式,引入这个库,由于是同一个项目,cargo 会自动找。引入后,就按模块的使用方法调用就行了,其它的测试标识与前面相同。

9.4 基准测试

单元测试是用来校验程序的正确性的,然而,程序能正常运行后,往往还需要测试程序(一部分)的执行速度,这时,就需要用到性能测试。 通常来讲,所谓性能测试,指的是测量程序运行的速度,即运行一次要多少时间(通常是执行多次求平均值)。Rust参照go实现了这部分内容。

推荐基准测试专门写在benches下,否则容易编译失败,在使用stable channel时。
例子如下:

#![feature(test)]
extern crate test;

extern crate rusttest;

#[cfg(test)]
mod testbinwen {
    use rusttest::add_two;
    use test::Bencher;

    #[bench]
    fn bench_add_two(b: &mut Bencher) {
        b.iter(|| add_two(2));
    }
}

评测函数fn bench_add_two(b: &mut Bencher) {}上面使用#[bench]做标注,同时函数接受一个参数,b 就是 Rust 提供的评测器。这个写法是固定的。
执行

cargo bench

即可获得结果。
可以看出,rust对测试的支持和go非常相似。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:bradyjoestar

查看原文:Rust学习笔记9 测试与评测

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

665 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传