11 测试

编写自动化测试

程序的正确性代码如我们期望的那样运行,Rust也在语言本身包含了编写软件测试的支持

本章我们会讲到编写测试时用到的注解和宏,运行测试的默认行为和选项,以及如何将测试组织成单元测试和集成测试

11.1 编写测试

Rust测试函数可以帮助我们测试代码,测试函数体通常执行以下三种操作:

1.设置任何所需的数据或状态

2.运行需要测试的代码

3.断言其结果是我们所期望的

让我们来看看Rust编写测试的功能:test属性、一些宏和should_panic属性

测试函数剖析

测试就是一个带有test属性的注解的函数。而属性是关于Rust代码片段的元数据.我们曾在结构体中用到的derive属性就是一个例子

为了将函数变成测试函数,需要在fn前加上 #[test].当使用 cargo test 命令行运行测试时,Rust会构建一个测试执行序用来调用标记了test属性的函数,并报告每一个测试是通过还是失败

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

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

C:\Users\jianquanqin>cargo new adder --libCreated library `adder` packageC:\Users\jianquanqin>cd adder

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

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

我们看到模块中有一个函数 it_works(),我们在它的前面加上了#[test] 属性表明它是一个测试函数,当然也可以在tests模块中添加非测试函数来帮助我们建立通用场景或进行常见操作

函数体通过使用assert_eq!来断言2加2等于4,它是一个典型的测试格式

运行一下,测试通过

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

通过查看结果,我们可以看到测试结果的明细

让我们改变测试的名称来看看测试输出

#[cfg(test)]
mod tests {#[test]fn it_works() {assert_eq!(2 + 2, 4);}
}
running 1 test
test tests::exploration ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

我们看到输出的结果也变了

让我们在tests模块中再增加一个测试 ,下面的失败测试函数和输出结果如我们所愿

#[cfg(test)]
mod tests {#[test]fn exploration() {assert_eq!(2 + 2, 4);}#[test]fn another() {panic!("Make this test fail");}
}
//
running 2 tests
thread 'test tests::exploration ... tests::anotherok' panicked at '
Make this test fail', src\lib.rs:10:9
stack backtrace:0: std::panicking::begin_panic<str>at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\library\std\src\panicking.rs:5411: adder::tests::anotherat .\src\lib.rs:102: adder::tests::another::closure$0at .\src\lib.rs:93: core::ops::function::FnOnce::call_once<adder::tests::another::closure$0,tuple$<> >at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\library\core\src\ops\function.rs:2274: core::ops::function::FnOnce::call_onceat /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b\library\core\src\ops\function.rs:227
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
test tests::another ... FAILEDfailures:failures:tests::anothertest result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s

使用assert!宏来检查结果

assert!宏由标准库提供,如果我们希望确保测试中一些条件为true,它将会非常有用。使用它是,我们得向它提供一个求值为布尔值得参数,如果值是true,assert!什么也不做,测试会通过。如果值为false,assert!调用panic!宏,这会导致测试失败。assert!宏帮助我们检查代码是否以期望的方式运行

我们来看一下之前的一个例子:

#[derive(Debug)]
struct Rectangle{width: u32,height:u32,
}
impl Rectangle {fn can_hold(&self,other:&Rectangle)->bool{self.width>other.width && self.height>other.height}
}

can_hold函数会返回一个布尔值, 符合我们使用assert!的条件

我们来编写一个测试函数

#[cfg(test)]
mod tests {use super::*;#[test]fn larger_can_hold_smaller() {let larger = Rectangle {width:8,height:7};let smaller = Rectangle{width:5,height:1};assert!(larger.can_hold(&smaller));}
}
//
running 1 test
test tests::larger_can_hold_smaller ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

测试通过,注意我们使用 use super:

The Rust Programming Language - 第11章 测试 - 11.1 编写测试相关推荐

  1. The Rust Programming Language - 第13章 Rust语言中的函数式语言功能:迭代器与闭包 - 13.1 可以捕获其环境的匿名函数

    13 Rust语言中的函数式语言功能:迭代器与闭包 函数式编程风格通常包括将函数作为另一个函数的参数.返回值,将函数作为值赋值给变量,以供后续执行 本章中我们将会介绍以下内容: 闭包:一个可以存储在变 ...

  2. The Rust Programming Language - 第19章 高级特征 - 19.5 宏

    19 高级特征 我们将在这一章学习更多高级功能 19.5 宏 宏指的是Rust中一系列功能,宏用macro_rules!来声明 三种过程宏: 1.自定义#[derive]宏在结构体和枚举上指定通过de ...

  3. The Rust Programming Language - 第18章 模式与模式匹配 - 18.2 Refutability(可反驳性):模式是否会匹配失效

    18 模式与模式匹配 模式是Rust中的特殊语法,用来匹配类型中的结构,无论类型复杂与否.模式由以下一些内容组合而成: 字面值\解构的数组.枚举.元组或者结构体\变量\通配符\占位符,这些部分描述了我 ...

  4. Java黑皮书课后题第11章:11.2(Person Student Employee Faculty Staff类)设计一个名为Person的类及其两个名为Student和Employee的子类

    Java黑皮书课后题第11章:11.2(Person Student Employee Faculty Staff类) 题目 缺陷 UML图 代码 Test02_MyDate.java:用于参考的My ...

  5. 怎样编写测试类测试分支_测试技巧–不编写测试

    怎样编写测试类测试分支 对此没有太多疑问,测试代码的方式是一个有争议的问题. 不同的测试技术由于各种原因(包括企业文化,经验和总体心理观点)而受到不同开发人员的青睐. 例如,您可能更喜欢编写经典的单元 ...

  6. 测试技巧–不编写测试

    对此没有太多疑问,测试代码的方式是一个有争议的问题. 不同的测试技术因各种原因(包括企业文化,经验和总体心理观点)而受到不同开发人员的青睐. 例如,您可能更喜欢编写经典的单元测试,通过检查返回值来单独 ...

  7. The Rust Programming Language - 前言

    前言 Rust程序设计语言本质在于赋能 Rust语言会涉及"系统层面"的工作,设计内存管理.数据表示和并发等底层细节(其实就是一些计算机系统.组成原理.数据结构.网络等方面的基础知 ...

  8. C++ Primer 第11章 习题11.16

    //11.16.cpp //使用copy算法将一个文件的内容写到标准输出中 #include<iostream> #include<cstdlib> #include<f ...

  9. Java黑皮书课后题第11章:11.3(Account类的子类)在编程练习题9.7中定义了一个Account类来对一个银行账户建模。一个账户有账号、余额、年利率、开户日期等属性,以及存款和取款等方法

    续标题:创建支票账户checking account和储蓄账户saving account两个子类.支票账户有一个透支限定额,但储蓄账户不能透支 题目(续) 题目中提到的编程练习题9.7:以下代码直接 ...

最新文章

  1. 数据归一化 - MinMaxScaler()/MaxAbsScaler() - Python代码
  2. Bootstrap Paginator分页插件+ajax
  3. 艾特某人代码实现_为何敲代码,学好数学很重要?
  4. 基于Redis优化首页轮播图查询
  5. 一句话讲清楚GIL锁
  6. *多叉树的树形背包常见建模方法
  7. Linux 基本操作--文件查看 (day3)
  8. sw如何缩放装配体_solidworks提高大型装配体的展示、设计效率
  9. 【预测模型】基于matlab BP神经网络预测【含Matlab源码 221期】
  10. 关于家庭路由器网络布线
  11. java项目-基于SSM实现物流信息管理系统
  12. ArcGIS 拓扑验证与编辑共享要素
  13. Check Point R80.10 SmartConsole汉化生成中文报表
  14. httpwatch professional 破解版v9.4.17
  15. 读书笔记3|使用Python,networkx对卡勒德胡赛尼三部曲之——《群山回唱》人物关系图谱绘制
  16. 从事java的年龄_请教前辈们:JAVA的职业有年龄限制吗
  17. 01 hbuilder账号的注册
  18. 融券余额大增,市场情绪极其悲观
  19. Kubernetes资源调度之污点与Pod容忍度
  20. spark笔记spark优化

热门文章

  1. 【C】C课程设计-驾校考试模拟系统
  2. Unity3D Behavior Designer 行为树1 认识
  3. 奥鹏西交计算机应用基础在线作业,20秋西交《计算机应用基础》在线作业【答案】...
  4. 树莓派3B安装linux(ubuntu mate 16.04.2)+ 远程桌面
  5. 将一个excel多个文件合并成一个文件的多个sheet
  6. cadence 通孔焊盘_Allegro 16.6创建通孔类焊盘步骤
  7. pcb元器件通孔焊盘激光焊锡的优势
  8. MySQL中单引号、双引号和反引号的区别
  9. 线上tomcat服务器假死排查
  10. 使用 电报机器人 tele bot 远程执行服务器上的命令