Rust之自动化测试(二):控制测试如何运行

开发环境

  • Windows 10
  • Rust 1.72.1

 

  • VS Code 1.82.2

 项目工程

这里继续沿用上次工程rust-demo

控制测试如何运行

 正如cargo run编译您的代码,然后运行生成的二进制文件一样,cargo test在测试模式下编译您的代码,然后运行生成的测试二进制文件。cargo test生成的二进制文件的默认行为是并行运行所有测试,并捕获测试运行期间生成的输出,从而防止显示输出,并使读取与测试结果相关的输出变得更容易。但是,您可以指定命令行选项来更改此默认行为。

一些命令行选项转到cargo test,一些转到结果测试二进制文件。为了区分这两种类型的参数,您列出了连接到cargo test的参数,后跟分隔符 --,然后是连接到测试二进制的参数。运行cargo test --help 显示您可以使用cargo test的选项,运行cargo test --help显示您可以在分隔符后使用的选项。 

并行或连续运行测试

当您运行多个测试时,默认情况下它们使用线程并行运行,这意味着它们运行得更快,您得到反馈也更快。因为测试是同时运行的,所以您必须确保您的测试不依赖于彼此或者任何共享状态,包括共享环境,比如当前的工作目录或者环境变量。

例如,假设您的每个测试运行一些代码,这些代码在磁盘上创建一个名为test-output.txt的文件,并将一些数据写入该文件。然后,每个测试读取该文件中的数据,并断言该文件包含特定的值,该值在每个测试中是不同的。因为测试是同时运行的,所以一个测试可能会在另一个测试写入和读取文件之间的时间内覆盖文件。第二个测试将会失败,不是因为代码不正确,而是因为测试在并行运行时相互干扰。一个解决方案是确保每个测试写入不同的文件;另一个解决方案是一次运行一个测试。

如果您不想并行运行测试,或者如果您想要对使用的线程数量进行更细粒度的控制,那么您可以向测试二进制文件发送- test-threads标志和想要使用的线程数量。看一下下面的例子:

$ cargo test -- --test-threads=1

我们将测试线程的数量设置为1,告诉程序不要使用任何并行性。使用一个线程运行测试将比并行运行测试花费更长的时间,但是如果它们共享状态,测试将不会相互干扰。

显示功能输出

 默认情况下,如果测试通过,Rust的测试库会捕获任何打印到标准输出的内容。例如,如果我们调用println!在测试中,如果测试通过,我们将看不到println!在终端中的输出;我们只会看到表示测试通过的那一行。如果一个测试失败了,我们将看到输出到标准输出中的内容以及失败消息的其余部分。

举例来说,示例11-10有一个简单的函数,它打印参数值并返回10,还有一个通过的测试和一个失败的测试。

文件名:src/lib.rs

fn prints_and_returns_10(a: i32) -> i32 {println!("I got the value {}", a);10
}#[cfg(test)]
mod tests {use super::*;#[test]fn this_test_will_pass() {let value = prints_and_returns_10(4);assert_eq!(10, value);}#[test]fn this_test_will_fail() {let value = prints_and_returns_10(8);assert_eq!(5, value);}
}

示例11-10:测试调用println!的函数

 当我们用cargo test运行这些测试时,我们将看到以下输出:

$ cargo testCompiling silly-function v0.1.0 (file:///projects/silly-function)Finished test [unoptimized + debuginfo] target(s) in 0.58sRunning unittests src/lib.rs (target/debug/deps/silly_function-160869f38cff9166)running 2 tests
test tests::this_test_will_fail ... FAILED
test tests::this_test_will_pass ... okfailures:---- tests::this_test_will_fail stdout ----
I got the value 8
thread 'tests::this_test_will_fail' panicked at 'assertion failed: `(left == right)`left: `5`,right: `10`', src/lib.rs:19:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtracefailures:tests::this_test_will_failtest result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00serror: test failed, to rerun pass `--lib`

请注意,在这个输出中,我们看不到I got the value 4,这是通过的测试运行时打印的内容。该输出已被捕获。失败的测试的输出:I got the value 8,出现在测试总结输出部分,它也显示了测试失败的原因。

如果我们还想看到通过测试的打印值,我们可以告诉Rust用- show-output显示成功测试的输出。 

$ cargo test -- --show-output

 当我们用- show-output标志再次运行示例11-10中的测试时,我们会看到下面的输出:

$ cargo test -- --show-outputCompiling silly-function v0.1.0 (file:///projects/silly-function)Finished test [unoptimized + debuginfo] target(s) in 0.60sRunning unittests src/lib.rs (target/debug/deps/silly_function-160869f38cff9166)running 2 tests
test tests::this_test_will_fail ... FAILED
test tests::this_test_will_pass ... oksuccesses:---- tests::this_test_will_pass stdout ----
I got the value 4successes:tests::this_test_will_passfailures:---- tests::this_test_will_fail stdout ----
I got the value 8
thread 'tests::this_test_will_fail' panicked at 'assertion failed: `(left == right)`left: `5`,right: `10`', src/lib.rs:19:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtracefailures:tests::this_test_will_failtest result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00serror: test failed, to rerun pass `--lib`

 

按名称运行测试子集

有时,运行一个完整的测试套件可能需要很长时间。如果您正在处理某个特定领域的代码,您可能希望只运行与该代码相关的测试。您可以通过将想要运行的测试的名称作为参数传递给cargo test来选择要运行的测试。

为了演示如何运行测试子集,我们将首先为add_two函数创建三个测试,如示例11-11所示,并选择要运行的测试。

文件名:src/lib.rs

pub fn add_two(a: i32) -> i32 {a + 2
}#[cfg(test)]
mod tests {use super::*;#[test]fn add_two_and_two() {assert_eq!(4, add_two(2));}#[test]fn add_three_and_two() {assert_eq!(5, add_two(3));}#[test]fn one_hundred() {assert_eq!(102, add_two(100));}
}

示例11-11:三个不同名称的三个测试

 如果我们运行测试而不传递任何参数,正如我们前面看到的,所有的测试将并行运行:

$ cargo testCompiling adder v0.1.0 (file:///projects/adder)Finished test [unoptimized + debuginfo] target(s) in 0.62sRunning unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4)running 3 tests
test tests::add_three_and_two ... ok
test tests::add_two_and_two ... ok
test tests::one_hundred ... oktest result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00sDoc-tests adderrunning 0 teststest result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

 运行单一测试

我们可以将任何测试函数的名称传递给cargo test,以便只运行该测试:

$ cargo test one_hundredCompiling adder v0.1.0 (file:///projects/adder)Finished test [unoptimized + debuginfo] target(s) in 0.69sRunning unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4)running 1 test
test tests::one_hundred ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s

只有名为one_hundred的测试运行;其他两项测试都不符合这个名字。测试输出让我们知道我们有更多的测试没有运行,通过在最后显示2 filtered out

我们不能以这种方式指定多个测试的名称;将只使用cargo test的第一个值。但是有一种方法可以运行多个测试。 

过滤以运行多个测试

 我们可以指定测试名称的一部分,任何名称与该值匹配的测试都将运行。例如,因为我们的两个测试名称包含add,所以我们可以通过运行cargo test add:

$ cargo test addCompiling adder v0.1.0 (file:///projects/adder)Finished test [unoptimized + debuginfo] target(s) in 0.61sRunning unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4)running 2 tests
test tests::add_three_and_two ... ok
test tests::add_two_and_two ... oktest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s

该命令运行名称中带有add的所有测试,并过滤掉名为one_hundred的测试。还要注意,测试所在的模块成为测试名称的一部分,因此我们可以通过过滤模块名称来运行模块中的所有测试。 

 除非特别要求,否则忽略一些测试

有时一些特定的测试执行起来非常耗时,因此您可能希望在大多数货cargo test期间排除它们。您可以使用ignore属性将耗时的测试排除在外,而不是将您想要运行的所有测试作为参数列出,如下所示:

文件名:src/lib.rs

#[test]
fn it_works() {assert_eq!(2 + 2, 4);
}#[test]
#[ignore]
fn expensive_test() {// code that takes an hour to run
}

 在#[test]之后,我们将#[ignore]行添加到我们想要排除的测试中。现在,当我们运行我们的测试时,it_works会运行,但是expensive_test不会:

$ cargo testCompiling adder v0.1.0 (file:///projects/adder)Finished test [unoptimized + debuginfo] target(s) in 0.60sRunning unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4)running 2 tests
test expensive_test ... ignored
test it_works ... oktest result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00sDoc-tests adderrunning 0 teststest result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

expensive_test函数被列为ignored。如果我们只想运行被忽略的测试,我们可以使用cargo test - - ignored:

$ cargo test -- --ignoredCompiling adder v0.1.0 (file:///projects/adder)Finished test [unoptimized + debuginfo] target(s) in 0.61sRunning unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4)running 1 test
test expensive_test ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00sDoc-tests adderrunning 0 teststest result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

 通过控制运行哪些测试,您可以确保cargo test结果会很快。当您有时间检查被ignored测试的结果并且有时间等待结果时,您可以运行cargo test - - ignored。如果你想运行所有的测试,不管它们是否被忽略,你可以运行cargo test -- --include-ignored

本章重点 

  • 如何控制测试的用途
  • 控制测试的方法
  • 并行或连续测试的方法
  • println!在测试中如何输出
  • 单一测试和过滤运行多个测试
  • 忽略测试的方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/144300.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

马尔萨斯《人口原理》读后

200 多年前的书,很多人都说旧的东西过时了,但我觉得它只是被修正了,内核并不过时。毕竟,静态存量分析这本身就不符合现实,用现在的话说,建模就错了,但马尔萨斯的理论核心并不仅仅是一个模型&…

华为多路径软件UltraPath

检查多路径是否安装。 # rpm -qa|grep UltraPath 查看UltraPath软件版本 # upadmin show version 查看物理路径状态。 #upadmin show path 查看虚拟磁盘信息。 #upadmin show vlun 查看逻辑路径状态。 #upadmin show vlun 查看多路径配置。 #upadmin show upconfig 卸载Ul…

brew 安装MySQL 5.7

写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成…

php导出cvs,excel打开数字超过16变科学计数法

今天使用php导出cvs,在excel中打开,某一个字段是数字,长度高于16位结果就显示科学计数法 超过15位的话从第16位开始就用0代替了 查询了半天总算解决了就是在后面加上"\t" $data[$key][1] " ".$value[1]."\t";…

你的游戏项目有这些问题吗?

在移动游戏对高品质画面的要求不断增加的背景下,我们一直专注于移动设备GPU性能的优化,以确保您的游戏体验得以最佳展现。然而,不同GPU芯片之间的性能差异以及由此可能引发的GPU瓶颈问题使得优化工作更加具有挑战性。 因此,在不久…

Spring Boot中配置文件介绍及其使用教程

目录 一、配置文件介绍 二、配置简单数据 三、配置对象数据 四、配置集合数据 五、读取配置文件数据 六、占位符的使用 一、配置文件介绍 SpringBoot项目中,大部分配置都有默认值,但如果想替换默认配置的话,就可以使用application.prop…

Spring结合自定义注解实现 AOP 切面功能

Spring结合自定义注解实现 AOP 切面功能 Spring AOP 注解概述Aspect 快速入门execution 切点表达式 拦截指定类的方法Pointcut("annotation(xx)") 拦截拥有指定注解的方法环绕通知 实现开关目标方法案例1:自定义注解切面实现统一日志处理1.自定义日志注解…

uni-app:获取元素宽高

效果 代码 这里我定义的宽为500px,高为200排序,控制台输出的结果是502,202。原因是我设置了上下左右宽度各为1px的border边框导致 核心代码分析 // const query uni.createSelectorQuery();表示创建了一个选择器查询实例。通过这个实例,你可以使用不同的方法来选择…

英语——分享篇——每日100词——501-600

hill——will愿意——他不愿意去小山里 Easter——east东方(熟词)er儿(拼音)——东方的儿子都过复活节 exhibition——ex前夫(熟词)hi嗨(熟词)bition比神(谐音)——展览会上前夫很嗨,比神还开心 chase——vt.追捕,追逐,追赶——cha茶se色——…

【C++】vector的介绍 | 常见接口的使用

目录 vector的介绍 常见接口 构造函数 尾插push_back() vector的遍历 1.用方括号下标 遍历: 2.调用at()来访问: 3.用迭代器遍历: 4.范围for遍历: vector空间 vector增删查改 覆盖assign() 查找find() 插入insert() …

Java on Azure Tooling 8月更新|以应用程序为中心的视图支持及 Azure 应用服务部署状态改进

作者:Jialuo Gan - Program Manager, Developer Division at Microsoft 排版:Alan Wang 大家好,欢迎阅读 Java on Azure 工具的八月更新。在本次更新中,我们将推出新的以应用程序为中心的视图支持,帮助开发人员在一个项…

Spring修炼之路(1)基础入门

一、简介 1.1Spring概述 Spring框架是一个轻量级的Java开发框架,它提供了一系列底层容器和基础设施,并可以和大量常用的开源框架无缝集成,可以说是开发Java EE应用程序的必备。Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器&…

【面试经典 150 | 滑动窗口】串联所有单词的子串

文章目录 写在前面Tag题目来源题目解读解题思路方法一:两个哈希表方法二:滑动窗口 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内容以分析题目为主,并附带一…

JS三大运行时全面对比:Node.js vs Bun vs Deno

全文约 5100 字,预计阅读需要 15 分钟。 JavaScript 运行时是指执行 JavaScript 代码的环境。目前,JavaScript 生态中有三大运行时:Node.js、Bun、Deno。老牌运行时 Node.js 的霸主地位正受到 Deno 和 Bun 的挑战,下面就来看看这…

计算机视觉与深度学习-循环神经网络与注意力机制-RNN(Recurrent Neural Network)、LSTM-【北邮鲁鹏】

目录 举例应用槽填充(Slot Filling)解决思路方案使用前馈神经网络输入1-of-N encoding(One-hot)(独热编码) 输出 问题 循环神经网络(Recurrent Neural Network,RNN)定义如何工作学习目标深度Elm…

Vue中自定义实现类似el-table的表格效果实现行颜色根据数据去变化展示

主要使用div布局实现表格效果&#xff0c;并使用渐变实现行背景渐变的效果 页面布局 <div class"table-wrap"><div class"table-title"><divv-for"(item, index) in tableColumn":key"index":prop"item.prop&qu…

Windows11安装MySQL8.1

安装过程中遇到任何问题均可以参考(这个博客只是单纯升级个版本和简化流程) Windows安装MySQL8教程-CSDN博客 到官网下载mysql8数据库软件 MySQL :: Download MySQL Community Server 下载完后,解压到你需要安装的文件夹 其中的配置文件内容了如下 [mysqld]# 设置3306端口po…

使用applescript自动化trilium的数学公式环境

众所周知&#xff0c;trilium什么都好&#xff0c;就是对数学公式的支持以及markdown格式的导入导出功能太拉了&#xff0c;而最拉的时刻当属把这两个功能结合起来的时候&#xff1a;导入markdown文件之后&#xff0c;原来的数学公式全没了&#xff0c;需要一个一个手动用ctrlm…

python安装第三方模块方法

正常情况下安装python第三方模块没啥说的&#xff0c;但是由于python安装模块默认是在外网下载安装&#xff0c;牵扯外网网速问题&#xff0c;所以可以配置下使用国内某镜像源来下载模块 python -m pip install xxxxxxxxxxx 和 pip install xxxxxxxxxx 的命令都可下载安装第三…

R语言用标准最小二乘OLS,广义相加模型GAM ,样条函数进行逻辑回归LOGISTIC分类...

原文链接&#xff1a;http://tecdat.cn/?p21379 本文我们对逻辑回归和样条曲线进行介绍&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 logistic回归基于以下假设&#xff1a;给定协变量x&#xff0c;Y具有伯努利分布&#xff0c; 目的是估计参数β。 回想一…