Rust中文翻译16

翻译 2015年07月08日 23:17:51
Page 75

Program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence. --Edsger W. Dijkstra

我们来讨论一下如何测试Rust代码.我们不会讨论如何正确的测试Rust代码.有很多正确的或错误的测试代码的思想.他们都是用了同样的基本工具,我们会向你展示如何使用它们.

4.2.1 test属性(attribute)
最简单的定义,一个Rust的测试就是一个被test属性标记的方法.让我们用Cargo来创建一个新的工程.

$cargo new adder
$cd adder

Cargo会自动帮你创建一个简单的测试例子,当你创建一个新的工程的时候.下面就是src/lib.rs的内容:

#[test]
fn it_works() {
}

注意这个#[test].这个属性说明它是一个测试函数.它现在没有函数体.但是足够通过测试了!我们可以使用cargo test来运行:


Page 76

Cargo编译了我们的代码并且运行.这里有两类输出:一类是我们写的测试,另一类是文档测试.我们会稍后讨论文档测试,现在来看看这个:

test it_works ... ok

注意it_works.它来自于我们的函数:

fn it_works() {

我们还得到了一个结论行:

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

那么为什么我们什么都没做就可以通过测试?任何没有panic!的测试都将通过测试,任何panic!的测试都将不通过测试.我们来让测试失败:

#[test]
fn it_works() {
    assert!(false);
}

assert!是一个宏,带有一个参数:如果参数是true,什么都不发生.如果参数是false,它就panic!.再运行一次:



Page 77

Rust指出我们的测试失败了:

test it_works ... FAILED

可以在如下行显示出来:

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

我们还得到了一个非零的状态码:

$echo $?
101

如果你想把cargo集成到其他工具中这个状态码就派上用场了.
我们可以修改我们的测试,通过添加另一个属性:should_panic:

#[test]
#[should_panic]
fn it_works() {
    assert!(false);
}

这次我们的测试如果panic了就会通过!如果完成了就不会通过.试一下:


Rust提供另一个宏,assert_eq!,它会比较两个参数是否相等:
#[test]
#[should_panic]
fn it_works() {
    assert_eq!("Hello", "world");
}

这个测试是否可以通过呢?因为有should_panic属性,它会通过测试:


should_panic测试是很脆弱的,它很难保证一些非预期的原因不会导致测试失败.为此,有另一个可选参数加入should_panic属性中.测试会保证失败信息中包含了参数中提供的字符串.一个更安全的版本如下:
#[test]
#[should_panic(expected = "assetion failed")]
fn it_works() {
    assert_eq!("Hello", "world");
}

上述都是基础!我们来写一个真正的测试:
pub fn add_two(a: i32) -> i32 {
    a + 2
}

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

这是一个非常平常的assert_eq!应用:调用一个函数,传递参数,然后比较它和预期输出值.

Page 79

4.2.2 tests模块

我们上述的例子有一个不太常用的问题:缺少tests模块.常用的方法是这样:
pub fb 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));
    }
}

这里有一些改动.第一就是引入了一个tests模块,带有属性cfg.这个模块让我们把测试分组,并且可以定义一些帮助方法,这些方法不会成为我们的crate的一部分.cfg属性仅仅编译我们的测试方法,如果我们只运行测试的话.这可以节约编译时间,同时确保我们的测试不在我们常规的编译中.

第二点是使用了use声明.因为我们在一个内部模块中,我们需要把我们的代码带入到作用域中.如果你使用了一个很大的模块可能这一点会很麻烦,这是glob属性的的常规用法.让我们修改代码:


注意不同的use行.我们来运行一下:

工作正常!
流行的惯例是使用tests模块来是我们的测试"单元化".任何测试函数都可以这样使用.那么"集成化"测试怎么办呢?为此,我们还有测试目录.

4.2.3 测试目录(tests directory)

为了写一个集成测试,我们需要一个tests目录,这样写tests/lib.rs文件:
extern crate adder;



看起来和之前的测试很像,但是有一点而不一样.我们在顶部有一个extern crate adder.那是因为tests目录下的测试是一个独立的crate,所以我们需要引入我们的库.tests也是我们写集成测试最合适的地方:他们使用这个库就像其他使用者一样.

运行一下:


现在我们有3个部分: 之前的和新的.
测试目录就讲这么多.测试模块在这里不是必须的.
最后我们来讲一下第三部分:文档测试.

相关文章推荐

Rust中文翻译20

Page 100 并发和并行在计算机科学中是非常重要的主题.在工业领域也很火.计算机如今有越来越多的核心,然而很多程序员还没有准备好使用它们. Rust安全的内存特性同样适用于并发存储.并发的...
  • zcmit
  • zcmit
  • 2015年07月11日 15:49
  • 1176

rust book 中文翻译

  • 2015年07月10日 12:03
  • 2.24MB
  • 下载

Rust中文翻译1

用kindle看trpl有一段时间了,由于总是在地铁里看,对知识的巩固和加深理解没有好处,还是决定自己翻译一遍吧,便于自己学习,也可以给其他人以参考. 平时加班太多了,我希望能坚持做完. 闲话不说,上...
  • zcmit
  • zcmit
  • 2015年06月14日 17:16
  • 2474

Rust中文翻译12

Page 63 我们已经学习了如何写一些Rust代码了.但是能写Rust代码和能写好的Rust代码又很大区别. 这一章讲述一些相对独立的指南,告诉你如何把的Rust代码更进一步.一...
  • zcmit
  • zcmit
  • 2015年07月03日 17:11
  • 822

苹果App Store审核指南中文翻译(2014.9.1更新)

CocoaChina对《苹果应用商店审核指南》中文翻译最近一次更新时间为2014-02-27,文中红色部分是相对于2014-02-27版本的新增内容,蓝色表示苹果相关官方文档的链接。...

Gitlab部署CI并使用.gitlab-ci.yml配置您的作业(中文翻译)

本文档描述了.gitlab-ci.ymlGitLab Runner用于管理项目作业的文件的用法。 如果您想快速介绍GitLab CI,请按照我们的 快速入门指南。 .gitlab-ci.yml ...

Android Audio音频部分官网文档中文翻译

Audio 安卓音频硬件抽象层(HAL)通过 android.media 包中的音频框架 API 函数将系统上层和底层的音频驱动与硬件实体 联系起来。这一章节的内容包括实现安卓音频功能的方法说明以...

james blunt no tears 歌词的中文翻译

来自 http://zhidao.baidu.com/question/197395361.html 上面那人的歌词少了开头两句。 don't I know it, nobody has to sa...
  • huyoo
  • huyoo
  • 2011年07月26日 00:26
  • 5399

DBCP2配置详细说明(中文翻译)

common-dbcp2数据库连接池参数说明 由于commons-dbcp所用的连接池出现版本升级,因此commons-dbcp2中的数据库池连接配置也发生了变化,具体的参数配置说明如下: ...
  • kerafan
  • kerafan
  • 2015年12月22日 23:10
  • 5436
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Rust中文翻译16
举报原因:
原因补充:

(最多只允许输入30个字)