Rust个人学习之单元测试

基础标记说明

Rust 是具备内嵌单元测试模块的。在 Rust 中,可以通过在源代码文件的顶部使用 #[test] 属性来标记一个函数作为测试函数。通常,这些测试函数位于与它们测试的源代码相同的文件中,但位于 mod tests 模块中。这是一个常用做法。
另外还有一个标记属性。#[cfg(test)] 是一个条件编译属性,它允许你编写只在测试构建中编译的代码。这对于定义只在测试时需要的辅助函数、类型或模块特别有用,从而避免在生产代码中引入不必要的开销或依赖。
创建一个测试代码:

fn im_true() -> bool {                                                                                                 true
}fn is_false() -> bool {false
}fn is_num_three() -> u32 {3
}fn is_string() -> String {String::from("hello")
}

接下来测试函数 is_false 的返回是否为布尔值:否,需要先建立一个测试模块,然后建立一个测试函数

#[cfg(test)]                                                                                                       mod test {use crate::is_false;#[test]// check if is_false return falsefn check_bool_false() {let f = is_false();assert!(!f, "is not false");}#[test]// check if return truefn check_bool_true() {let f = is_false();assert!(f, "is not true");}}

上面的代码中建立了一个名字为 test 的测试模块,由于标记了#[cfg (test)]标签,所以在执行 cargo build 时是不会执行编译的,只有在执行 cargo test 时会编译执行。另外建立了两个单元测试内容:check_bool_false, check_bool_true,两个函数都用#[test]进行了标记。当执行 cargo test 时会看到两个测试项的结果。上述代码比较简单,应该是一个成功一个失败:

#cargo test
......
running 2 tests
test test::check_bool_false ... ok
test test::check_bool_true ... FAILEDfailures:---- test::check_bool_true stdout ----
thread 'test::check_bool_true' panicked at src/main.rs:37:9:
is not true
note: run with `RUST_BACKTRACE=1` environment variable to display a backtracefailures:test::check_bool_truetest result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00serror: test failed, to rerun pass `--bin unitestlearn`

成功的单元测试会描述为 ok,而失败的会使用:FAILED 标记进行提示。同时会有标准输出以及总结哪些测试用例失败的描述。

断言

上述代码中有个关键字 assert!,这个关键字是检查给定的布尔表达式是否为真。如果为假,则测试失败。类似的关键字还有很多

关键字说明
assert!检查给定的布尔表达式是否为真。如果为假,则测试失败。
assert_eq!检查两个表达式是否相等。如果不等,则测试失败
assert_ne!检查两个表达式是否不相等。如果相等,则测试失败
Assert_debug_snapshot!用于比较当前代码的调试输出是否与先前存储的快照匹配,这有助于在重构代码时确保其行为未改变 (依赖 insta )

以下是一些案例

#[test]     ----- 布尔值检查
// check if return true
fn check_bool_true() {let f = im_true();assert!(f, "is not true");
}#[test]     ---- 数字相等检查
fn check_equal_num() {assert_eq!(2,2);
}#[test]     ----- 数字不等检查
fn check_ne_num() {assert_ne!(3,2);
}#[test]     ----- 快照检查
fn check_snapshot() {let mut settings = insta::Settings::clone_current();settings.set_snapshot_path("../test/snapshot/");settings.bind(|| {let name = "helloworld";insta::assert_debug_snapshot!(name);});
}

快照检查需要多说一下,写快照检查时需要引入一个依赖,所以在 Cargo. Toml 中需要增加如下内容

[dependencies]
insta = "1.38.0"

在项目目录下创建一个 test/snapshot 目录,该目录将作为快照存储的目录,代码中采用 settings.set_snapshot_path 进行设置,settings. Bind 中设置测试流程,第一次执行时测试用例会失败,并自动在快照目录下生成一个快照文件,如上面的用例会生成一个:unitestlearn__test__check_snapshot.snap. New 的文件,生成后将该文件 new 的后缀去掉后保存就作为一个快照保存即可。

声明式宏

在 Rust 中可以通过 macro_rules!进行声明式宏的定义。能够减少重复代码的编写,简化代码,大大提高可读性和编码效率。
以下面为例:

macro_rules! snapshot_test {
($testname:ident, $txtcontent:literal) => {#[test]fn $testname() {let mut settings = insta::Settings::clone_current();settings.set_snapshot_path("../test/snapshot/");settings.bind(|| {let name = $txtcontent;insta::assert_debug_snapshot!(name);});}}  
}snapshot_test!(a_check, "a_check");                      
snapshot_test!(b_check, "b_check");
snapshot_test!(c_check, "c_check");

类似这种及其相似的代码就可以使用宏定义的方式快速实现。Macro_rules 的格式为

macro_rules! [宏定义名称] {() => {}// 其中括号为入参,大括号为函数体
}

针对宏定义的参数类型有以下几种

类型说明
ident标识符,如变量名或函数名。
block代码块,包括 { ... } 内的所有内容。
stmt语句,如赋值或函数调用。
expr表达式,可以求值为某个值的代码片段。
pat模式,用于匹配值或解构数据。
ty类型表达式,如 intVec<T>
lifetime生命周期标注,如 'a
literal字面量,如字符串、整数或浮点数字面量。
path路径,用于引用模块、类型或值。
meta元项,如属性(attributes)。
tt令牌树(token tree),可以包含任何有效的 Rust 令牌。
item项,可以是一个函数、结构体定义等。
vis可见性修饰符,如 pubpriv

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

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

相关文章

空和null是两回事

文章目录 前言 StringUtils1. 空&#xff08;empty&#xff09;&#xff1a;字符串&#xff1a;集合&#xff1a; 2. null&#xff1a;引用类型变量&#xff1a;基本类型变量&#xff1a; 3. isBlank总结&#xff1a; 前言 StringUtils 提示&#xff1a;这里可以添加本文要记录…

日志打印的学习之log4j2(二)进阶案例

日志级别简述&#xff1a; trace追踪&#xff0c;就是程序推进一下&#xff0c;可以写个trace输出debug调试&#xff0c;一般作为最低级别&#xff0c;trace基本不用。info输出重要的信息&#xff0c;使用较多warn警告&#xff0c;有些信息不是错误信息&#xff0c;但也要给程…

计算机网络——35什么是网络安全

什么是网络安全 机密性&#xff1a;只有发送方和预订的接收方能否理解传输的报文内容 发送方加密报文接收方解密报文 认证&#xff1a;发送方和接收方需要确认对方的身份报文完整性&#xff1a;发送方、接收方需要确认的报文在传输的过程中或者事后没有被改变访问控制和服务的…

如何通过C++身份证实名认证接口实现实名认证功能

线上平台使用身份核验过程是验证个人身份真实性的过程&#xff0c;对于大多数线上平台来说&#xff0c;自己去开发集成身份证实名认证接口需要耗费大量的人力、物力成本&#xff0c;对此&#xff0c;为助力有需要的企业快速实现实名认证的功能&#xff0c;翔云平台提供了身份证…

利用nginx-http-flv-module实现三种直播

目录 一、说明 二、目标 三、实现 四、直播地址 一、说明 此文在《流媒体服务器的搭建(支持hls)》《搭建nginx-http-flv-module直播系统》之后编写,很多详细内容需要参考它。 流媒体服务器的搭建(支持hls)

力扣爆刷第112天之CodeTop100五连刷46-50

力扣爆刷第112天之CodeTop100五连刷46-50 文章目录 力扣爆刷第112天之CodeTop100五连刷46-50一、148. 排序链表二、22. 括号生成三、70. 爬楼梯四、2. 两数相加五、165. 比较版本号 一、148. 排序链表 题目链接&#xff1a;https://leetcode.cn/problems/sort-list/descriptio…

数据结构——顺序表(C语言)

目录 一、顺序表概念 二、顺序表分类 1.静态顺序表 2.动态顺序表 三、顺序表的实现 1.顺序表的结构体定义 2. 顺序表初始化 3.顺序表销毁 4.顺序表的检验 5.顺序表打印 6.顺序表扩容 7.顺序表尾插与头插 8.尾删与头删 9.在pos处插入数据 10.在pos处删除数据 11.查找数据 …

端盒日记Day02

JS 本本本本本地存储 localStorage 作用&#xff1a;可以将数据永久存储在本地&#xff08;用户电脑&#xff09;&#xff0c;除非手动删除&#xff0c;否则关闭页面也会存在 特性&#xff1a;a.可多窗口&#xff08;页面&#xff09;共享&#xff08;同一浏览器可以共享&a…

若依:一个基于Spring Boot、Spring Security、JWT、Vue和Element的全部开源快速开发平台

若依后台管理系统&#xff1a;一个基于Spring Boot、Spring Security、JWT、Vue和Element的全部开源快速开发平台 一、引言 随着软件开发技术的发展&#xff0c;前后端分离的开发模式逐渐成为主流。这种模式能够提高开发效率&#xff0c;降低维护成本&#xff0c;使前后端工程…

C++实现单例模式

#include <iostream> class Singleton { private: static Singleton* instance; // 指向单例实例的指针 Singleton() {} // 私有构造函数 public: // 获取单例对象的唯一全局访问点 static Singleton* getInstance() { if (instance nullpt…

c# wpf template itemtemplate+ListBox

1.概要 2.代码 <Window x:Class"WpfApp2.Window7"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/…

Kafka参数介绍

官网参数介绍:Apache KafkaApache Kafka: A Distributed Streaming Platform.https://kafka.apache.org/documentation/#configuration

开源大语言模型(LLM)汇总(持续更新中)

随着ChatGPT的火爆&#xff0c;越来越多人希望在本地运行一个大语言模型。为此我维护了这个开源大语言模型汇总&#xff0c;跟踪每天不发的大语言模型和精调语言模型。 我将根据个模型采用的基础大模型进行分类&#xff0c;每个大模型下列出各派生模型。 Alpaca (Stanford) 斯…

STM32CubeIDE基础学习-通用定时器中断实验

STM32CubeIDE基础学习-通用定时器中断实验 文章目录 STM32CubeIDE基础学习-通用定时器中断实验前言第1章 工程配置1.1 工程外设配置部分1.2 生成工程代码部分 第2章 代码编写第3章 实验现象总结 前言 生活中很多应用都有用到定时器功能、计时功能等。 定时器中断可以大大降低…

Win10文件夹共享(有密码的安全共享)(SMB协议共享)

前言 局域网内&#xff08;无安全问题&#xff0c;比如自己家里wifi&#xff09;无密码访问&#xff0c;参考之前的操作视频 【电脑文件全平台共享、播放器推荐】手机、电视、平板播放硬盘中的音、视频资源 下面讲解公共网络如办公室网络、咖啡厅网络等等环境下带密码的安全…

python爬虫———post请求方式(第十四天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

C++学习笔记(五)

临时对象与C11右值引用 右值&#xff1a;不可取地址的值是右值。左值&#xff1a;可以取地址就是左值。 -------------------------------------- 临时对象&#xff1a; ----------------- 临时对象的特性&#xff1a; -------------------- 系统不分配地址&#xff0c;在下一…

android wifi连接

记住密码&#xff0c;第二次登录不必输入。 如果使用其他方式&#xff0c;可不可以。其实就是自己选择wifi。 ******************** 我根本没办法站在更高的维度去思考整个项目&#xff0c;认知也达不到&#xff0c;我很多的事情都不知道&#xff08;信息不全&#xff09;&…

力扣经典150题第二题:移除元素

移除元素问题详解与解决方法 1. 介绍 移除元素问题是 LeetCode 经典题目之一&#xff0c;要求原地修改输入数组&#xff0c;移除所有数值等于给定值的元素&#xff0c;并返回新数组的长度。 问题描述 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等…

关于阿里云中RDS数据库的CPU使用率和内存使用率的20道高级面试题2

1. 什么是RDS数据库的CPU使用率&#xff1f;如何监控和管理它&#xff1f; RDS数据库的CPU使用率指的是数据库在执行各项操作时对CPU资源的占用情况。监控和管理CPU使用率可以通过RDS管理控制台来实现。 RDS管理控制台提供了多种工具和方法来查看和监控CPU的使用情况&#xf…