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

news2024/12/23 8:56:21

开发环境

  • 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 test
   Compiling silly-function v0.1.0 (file:///projects/silly-function)
    Finished test [unoptimized + debuginfo] target(s) in 0.58s
     Running 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 ... ok

failures:

---- 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 backtrace


failures:
    tests::this_test_will_fail

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`

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

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

$ cargo test -- --show-output

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

$ cargo test -- --show-output
   Compiling silly-function v0.1.0 (file:///projects/silly-function)
    Finished test [unoptimized + debuginfo] target(s) in 0.60s
     Running 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 ... ok

successes:

---- tests::this_test_will_pass stdout ----
I got the value 4


successes:
    tests::this_test_will_pass

failures:

---- 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 backtrace


failures:
    tests::this_test_will_fail

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`

 

按名称运行测试子集

有时,运行一个完整的测试套件可能需要很长时间。如果您正在处理某个特定领域的代码,您可能希望只运行与该代码相关的测试。您可以通过将想要运行的测试的名称作为参数传递给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 test
   Compiling adder v0.1.0 (file:///projects/adder)
    Finished test [unoptimized + debuginfo] target(s) in 0.62s
     Running 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 ... ok

test result: ok. 3 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

 运行单一测试

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

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

running 1 test
test tests::one_hundred ... ok

test 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 add
   Compiling adder v0.1.0 (file:///projects/adder)
    Finished test [unoptimized + debuginfo] target(s) in 0.61s
     Running 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 ... ok

test 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 test
   Compiling adder v0.1.0 (file:///projects/adder)
    Finished test [unoptimized + debuginfo] target(s) in 0.60s
     Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4)

running 2 tests
test expensive_test ... ignored
test it_works ... ok

test result: ok. 1 passed; 0 failed; 1 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

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

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

running 1 test
test expensive_test ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 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

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

本章重点 

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机网络笔记五】应用层(二)HTTP报文

HTTP 报文格式 HTTP 协议的请求报文和响应报文的结构基本相同,由四部分组成: ① 起始行(start line):描述请求或响应的基本信息;② 头部字段集合(header):使用 key-valu…

VR全景智慧文旅解决方案,助力文旅产业转型升级

引言: 随着科技的不断发展,虚拟现实(VR)技术正逐渐展露其影响力,改变着旅游业。VR全景智慧文旅解决方案也应运而生,将传统旅游的体验形式从线下扩展到了线上,带来了不一般的文旅体验。 一.VR全…

pandas--->CSV / JSON

csv CSV(Comma-Separated Values,逗号分隔值,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。 CSV 是一种通用的、相对简单的文…

优秀工具|使用Reqable替换处理过的动态混淆js

关注它,不迷路。 本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除! 1. 目标地址 这篇文章 爬虫神器|这是我过Debugger检测最简单的方法&a…

Qt地铁智慧换乘系统浅学( 二 )将存储的站点线路信息绘制到graphicsView(图形视图部件)

绘制 容器使用测试 画一个黑点到QGraphicsview中准备工作代码 绘制所有站点信息画线路信息准备工作代码 实现放大缩小功能放大缩小按键和建立与槽函数的连接槽函数实现效果如下bug 容器使用 Qt地铁智慧换乘系统浅学( 1) 测试 画一个黑点到QGraphicsvie…

JupyterNotebook的快捷键

Jupyter Notebook 有两种键盘输入模式:1、命令模式,键盘输入运行程序命令;这时的单元框线是蓝色。2、编辑模式,允许你往单元中键入代码或文本;这时的单元框线是绿色的。 一、命令模式 (在编辑模式下按键 Esc键进入命令…

RISC-V 指令

RISC-V指令都是32位长。 文章目录 R-Type指令格式:I-Type指令格式:S-Type指令格式:B-Type指令格式:U-Type指令格式:UJ-Type指令格式:J-Type指令格式:R4-Type指令格式:F-Type指令格式:vC-Type指令格式:CB-Type指令格式:CIW-Type指令格式:CL-Type指令格式:R-Type指…

华为云Stack的学习(八)

九、华为云Stack网络服务介绍 1.网络服务概览 1.1 租户界面的网络服务 租户登入ManageOne运营面后,可在服务列表中查看到网络服务。用户使用网络服务前管理员需要在Service OM上提前创建好外部网络。 1.2 华为云Stack网络服务全景图 1.3 网络服务承载网元 2.虚拟…

SpringMVC 学习(七)JSON

9. JSON 9.1 简介 JSON(JavaScript Object Notation,JS 对象标记)是一种轻量级数据交换格式,采用独立于编程语言的文本格式储存和表示数据,易于机器解析和生成,提升网络传输效率。 任何 JavaScript 支持…

IntelliJ IDEA 上 使用git 合并其他分支,合并某一个提交

git 合并其他分支 找到git——>merge… 选择需要合并的分支,不能选和当前分支一样噢 合并,推送即可 合并某个提交到其他分支 点击左下角git——>右键切换分支——>选择需要合并的分支——>选择需要合并的代码——>ch 推送即可

一篇文章彻底搞懂熵、信息熵、KL散度、交叉熵、Softmax和交叉熵损失函数

文章目录 一、熵和信息熵1.1 概念1.2 信息熵公式 二、KL散度和交叉熵2.1 KL散度(相对熵)2.2 交叉熵 三、Softmax和交叉熵损失函数3.1 Softmax3.2 交叉熵损失函数 一、熵和信息熵 1.1 概念 1. 熵是一个物理学概念,它表示一个系统的不确定性程度,或者说是…

redis(3)-hiredis-API函数的调用

1.API函数查询 http://github.com.redis/hiredis 2.直接在hiredis目录下新建 test_redis.c 2.1创建文件: 目录下有hiredis 2.2编译 添加环境变量 2.3运行 ./a.out 直接运行 redis-cli get itc…

算法-贪心+优先级队列-IPO

算法-贪心优先级队列-IPO 1 题目概述 1.1 题目出处 https://leetcode.cn/problems/ipo/description/?envTypestudy-plan-v2&envIdtop-interview-150 1.2 题目描述 2 回溯法 2.1 思路 2.2 代码 class Solution {int result 0;public int findMaximizedCapital(int …

基于ARM+FPGA的ISA总线/MMи总线接口转换设计在轨道交通的应用

总线广泛应用于计算机、工业生产及各种测试设备。ISA总线为IBM公司推出的基于80286CPU的PC/AT微型计算机用扩展总线标准,MMи总线是俄罗斯国内自行设计的专用测试总线,主要用于程控单元模块与MMи总线之间数据及控制信息的交换。在某型导弹测…

竞赛 基于深度学习的视频多目标跟踪实现

文章目录 1 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的视频多目标跟踪实现 …

HBase基础架构及存储原理

一、HBase介绍 HBase是Hadoop生态系统中的一个分布式、面向列的开源数据库,具有高可伸缩性、高性能和强大的数据处理能力。广泛应用于处理大规模数据集。 HBase是一种稀疏的、分布式、持久的多维排序map 稀疏:对比关系型数据库和非关系型数据库&#xf…

ubuntu下网卡插入网线后仍然不连接

网卡驱动已经安装,在settings里可以看到该网卡设备,但是插入网线后仍然不会连接: 鼠标点击也无效。 可尝试: 1. ifconfig找到该网卡,比如我的网卡是 enx0826ae3e81aa 2. sudo ifconfig enx0826ae3e81aa down sud…

OpenCV两张图片实现稀疏点云的生成

1 E矩阵 1.1 由F到E E K T ∗ F ∗ K E K^T * F * K EKT∗F∗K E 矩阵可以直接通过之前算好的 F 矩阵与相机内参 K 矩阵获得 Mat E K.t() * F * K;相机内参获得的方式是一个较为复杂的方式,需要使用棋盘进行定位获得,我们这里直接使用了 OpenMVG 提…

C语言学习(1)—— 环境安装和配置

运行C语言和C程序需要安装MinGW和VSCode。 一. 安装MinGW 1、进入官网下载MinGW:https://sourceforge.net/projects/mingw-w64/files/ 2、解压缩 3、配置环境变量 4、检查是否安装成功 二. 安装VSCode 1、进入官网下载VSCode:https://code.visualstud…

中国制造让苹果跪服,将再增加一家中国高科技供应商

日前产业链人士指出由于京东方的OLED面板有力地制衡韩国面板厂商三星和LGD,促使他们降价,而且技术也不错,因此正计划再引入一家中国OLED面板厂商,以进一步促进OLED面板的竞争。 早期苹果的OLED面板完全由三星供应,由此…