【Rust自学】11.10. 集成测试
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)

11.10.1. 什么是集成测试
在Rust里,集成测试完全位于被测试库的外部。集成测试调用库的方式和其他代码一样,这也意味着集成测试只能调用对外公开的API。
集成测试的目的是验证被测试库的多个部分能否正确地一起工作,这一点有别于单元测试,单元测试比较小也比较专注,每次只对一个模块进行隔离的测试,还可以测试私有的(private)接口。
有时候能够独立运行的一些单元代码在合在一起运用时也会发生问题,集成测试正是为了今早发现和解决这种问题存在的。所以说,集成测试的覆盖率很重要。
11.10.2. tests目录
创建集成测试需要先创建tests目录。
这个目录是与src目录并列,cargo会自动在这个目录下寻找集成测试文件。在这个目录下可以创建任意多的集成测试文件,cargo会在编译时把每个测试文件都处理为一个单独的包,也就是一个单独的crate。
下面来演示一下创建集成测试文件:
1. 创建tests目录
在与src同级的目录下创建名为tests的文件夹:

2. 创建测试文件
在tests目录下创建.rs的测试文件,给它取个名字,这里我起的是integration_test.rs:

3. 把测试代码移到测试文件里
以上一篇文章的代码为例(lib.rs):
pub fn add_two(a: usize) -> usize {internal_adder(a, 2)
}fn internal_adder(left: usize, right: usize) -> usize {left + right
}#[cfg(test)]
mod tests {use super::*;#[test]fn internal() {let result = internal_adder(2, 2);assert_eq!(result, 4);}
}
由于每一个集成测试文件都是一个单独的crate,所以这个文件(integration_test.rs)想要测试lib.rs这个crate的内容就得先导入作用域。
在这个例子中,由于我给这个项目命名为RustStudy,所以这个package(包)的名字就是RustStudy,如果你不清楚可以到你的cargo.toml里看name这个参数。在这个例子中,导入作用域写:use RustStudy;即可,如果你想指定到具体的函数也行。
导入完后直接写测试函数就可以,不需要写#[cfg(test)],因为tests目录下的代码只会在运行cargo test的时候被执行,只需要给测试函数标注#[test]即可。
整体代码如下(integration_test.rs):
use RustStudy;#[test]
fn it_adds_two() {let result = RustStudy::add_two(2);assert_eq!(result, 4);
}
输出:
$ cargo testCompiling adder v0.1.0 (file:///projects/adder)Finished `test` profile [unoptimized + debuginfo] target(s) in 1.31sRunning unittests src/lib.rs (target/debug/deps/adder-1082c4b063a8fbe6)running 1 test
test tests::internal ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00sRunning tests/integration_test.rs (target/debug/deps/integration_test-1082c4b063a8fbe6)running 1 test
test it_adds_two ... oktest result: ok. 1 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
可以看到,这个输出显示运行了两个测试,这是因为一个是来自lib.rs的测试(单元测试),一个是来自integration_test.rs的测试(集成测试)。
11.10.3. 运行指定的集成测试
运行一个特定的集成函数,可以使用cargo test 指定的函数名;运行某个测试文件内的所有测试函数,可以使用cargo test --test 文件名。
看个例子:

现在tests下有两个文件,如果我只希望运行integration_test.rs里的测试函数,那么就输入指令:
cargo test --test integration_test
11.10.4. 集成测试中的子模块
由于tests目录下的每个文件被编译成单独的crate,所以这些文件互不共享行为(与src目录下的文件规则不同)。
那如果我想将测试函数中重复出现的逻辑提取到一个helper函数中,避免代码重复,该怎么写呢?
举个例子,我在tests目录下写了common.rs这个文件用于存储helper函数:

试试执行测试:
$ cargo testCompiling adder v0.1.0 (file:///projects/adder)Finished `test` profile [unoptimized + debuginfo] target(s) in 0.89sRunning unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4)running 1 test
test tests::internal ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00sRunning tests/common.rs (target/debug/deps/common-92948b65e88960b4)running 0 teststest result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00sRunning tests/integration_test.rs (target/debug/deps/integration_test-92948b65e88960b4)running 1 test
test it_adds_two ... oktest result: ok. 1 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
可以看到,在测试结果中出现了对common.rs的测试。但因为common.rs是用来存储helper函数的,所以它本身不需要也没必要被测试,这种写法是错误的。
正确的做法是在tests目录下创建一个common目录,在里面创建mod.rs,把helper函数都放到这里面来,把原来的common.rs删掉即可:

这实际上是另外一种可以被Rust理解的命名规范,Rust不会把common模块视作为集成测试文件,而在测试输出中也不会出现common了,因为tests下的子目录不会被视为单独的crate进行编译。
如果要在集成测试文件中使用这里面的内容,只需要在文件开头写mod 文件夹名;即可,在这个例子中就是mod common;。使用时写common::你想要的函数,在这个例子中就是common::setup()
11.10.5. 针对binary crate的集成测试
如果项目是二进制包(binary crate),也就是只含有src/main.rs没有src/lib.rs,就不可以在tests目录下创建集成测试,即使有,也无法把main.rs的函数导入作用域。因为只有library crate(也就是有lib.rs)才能暴露函数给其它crate用。
binary crate意味着独立运行。因此,Rust的binary项目通常会把这些逻辑都放在lib.rs里,而在main.rs里只有简单的调用。这样做项目就会被视为library crate,就可以使用集成测试来检查代码。
相关文章:
【Rust自学】11.10. 集成测试
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 11.10.1. 什么是集成测试 在Rust里,集成测试完全位于被测试库的外部。集成测试调用库的方式和其他代码一样,这也…...
对当前日期进行按年、按月、按日的取值
对当前日期进行按年、按月、按日的取值。 其规则为: 按年 为当前日期到来年同一日期的前一天(2024-12-01到2025-11-30)。 按月 为当前日期到下个月的同一日期的前一天 (2024-12-01 到 2024-12-31)。 按日 为当前日…...
【Rust自学】12.2. 读取文件
12.2.0. 写在正文之前 第12章要做一个实例的项目——一个命令行程序。这个程序是一个grep(Global Regular Expression Print),是一个全局正则搜索和输出的工具。它的功能是在指定的文件中搜索出指定的文字。 这个项目分为这么几步: 接收命令行参数读…...
C++内存泄露排查
内存泄漏是指程序动态分配的内存未能及时释放,导致系统内存逐渐耗尽,最终可能造成程序崩溃或性能下降。在C中,内存泄漏通常发生在使用new或malloc等分配内存的操作时,但没有正确地使用delete或free来释放这块内存。 在日常开发过程…...
Http 响应状态码 前后端联调
http 响应状态码 :是服务器在处理HTTP请求时返回的状态信息,用于表示请求的处理结果 1xx : 信息性状态码 100 Continue: 服务器已收到请求头部,客户端应继续发送请求体。 101 Switching Protocols : 切换协议。服务器已理解客户端的请求&a…...
48_Lua错误处理
在编写Lua应用时,都可能会遇到不可预见的错误,而错误处理是确保程序稳定性和健壮性的关键环节。有效的错误处理不仅能防止程序崩溃,还能提供有用的反馈信息给开发者或最终用户,从而提高应用程序的质量。本文将详细介绍Lua中的错误处理机制。 1.错误类型 Lua中的错误类型主…...
shell脚本回顾1
1、shell 脚本写出检测 /tmp/size.log 文件如果存在显示它的内容,不存在则创建一个文件将创建时间写入。 一、 ll /tmp/size.log &>/dev/null if [ $? -eq 0 ];then cat /tmp/size.log else touch /tmp/size.log echo date > /tmp/size.log fi二、 if …...
【3】管理无线控制器
1.概述 本文主要介绍AireOS WLC的管理。WLC的管理可以通过CLI和GUI两种方式,而CLI主要分为console接入、telnet以及SSH的登录管理;GUI的管理分为HTTP和HTTPS。 2.CLI的管理 通过console实现的CLI管理这里就单独进行说明了,只要能找到设备的console接口,通过一般的RJ45接…...
SOME/IP 协议详解——服务发现
文章目录 1. Introduction (引言)2. SOME/IP Service Discovery (SOME/IP-SD)2.1 General(概述)2.2 SOME/IP-SD Message Format2.2.1 通用要求2.2.2 SOME/IP-SD Header2.2.3 Entry Format2.2.4 Options Format2.2.4.1 配置选项(Co…...
Flutter:封装ActionSheet 操作菜单
演示效果图 action_sheet_util.dart import package:ducafe_ui_core/ducafe_ui_core.dart; import package:flutter/material.dart; import package:demo/common/index.dart;class ActionSheetUtil {/// 底部操作表/// [context] 上下文/// [title] 标题/// [items] 选项列表 …...
力扣 全排列
回溯经典例题。 题目 通过回溯生成所有可能的排列。每次递归时,选择一个数字,直到选满所有数字,然后记录当前排列,回到上层时移除最后选的数字并继续选择其他未选的数字。每次递归时,在 path 中添加一个新的数字&…...
Golang 设计模式
文章目录 创建型模式简单工厂模式图形接口具体图形类:圆形具体图形类:矩形工厂类定义使用简单工厂模式 抽象工厂模式1. 定义产品接口2. 定义具体产品实现类3. 定义抽象工厂接口4. 定义具体工厂实现类5. 使用抽象工厂创建对象并使用产品 创建者模式1. 定义…...
Matlab 具有周期性分布的死角孔的饱和空气多孔材料的声学特性
本文对直主孔含侧空腔(死角)的饱和空气多孔介质中的声传播进行了理论和数值研究。侧腔位于沿每个主孔周期性间隔的“节点”上。研究了侧向空腔分布中周期性的影响,并单独考虑了紧间隔死角的低频极限。结果表明,吸附系数和透射损失…...
maven 项目怎么指定打包后名字
在 Spring Boot 的 Maven 项目中,你可以通过配置 pom.xml 文件来指定打包后的文件名。具体步骤如下: 打开 pom.xml 文件:找到你的项目根目录下的 pom.xml 文件。 配置 finalName 属性:在 标签下,添加 属性来指定打包后…...
Java Web开发进阶——Spring Boot与Thymeleaf模板引擎
Thymeleaf 是一个现代化的、功能强大的 Java 模板引擎,常用于生成 Web 应用程序的视图。它与 Spring Boot 的集成十分方便,并且提供了丰富的功能,能够帮助开发者实现动态渲染数据、处理表单、页面控制等操作。下面,我们将详细探讨…...
论文笔记(四十七)Diffusion policy: Visuomotor policy learning via action diffusion(下)
Diffusion policy: Visuomotor policy learning via action diffusion(下) 文章概括5. 评估5.1 模拟环境和数据集5.2 评估方法论5.3 关键发现5.4 消融研究 6 真实世界评估6.1 真实世界Push-T任务6.2 杯子翻转任务6.3 酱汁倒入和涂抹任务 7. 实际双臂任务…...
开始使用Panuon开源界面库环境配置并手写VS2019高仿界面
1. Panuon环境配置 1.1. 通过Nuget 安装 Panuon.WPF.UI1.2. xaml引用命名空间1.3. using Panuon.WPF.UI; 2. VS2019 view 2.1. 设置窗体尺寸和title2.2. 添加静态资源 2.2.1. 什么是静态资源 2.3. 主Grid 2.3.1. 盒子模型2.3.2. 嵌套布局 3. 总结 1. Panuon环境配置 1.1. 通…...
新垂直电商的社交传播策略与AI智能名片2+1链动模式S2B2C商城小程序的应用探索
摘要:随着互联网技术的不断进步和电商行业的快速发展,传统电商模式已难以满足消费者日益增长的个性化和多元化需求。新垂直电商在此背景下应运而生,通过精准定位、用户细分以及深度社交传播策略,实现了用户群体的快速裂变与高效营…...
WPS计算机二级•表格函数计算
听说这里是目录哦 函数基础知识 相对绝对混合引用🌪️相对引用绝对引用混合引用 常用求和函数 SUM函数🌦️语法说明 函数快速求 平均数最值⚡平均数最值 实用统计函数 实现高效统计🌀COUNTCOUNTIF 实用文本函数 高效整理数据🌈RIG…...
ESP32S3官方例程如何使用
一、WIFI 找到app_wifi.c文件 wifi_config_t wifi_config; 把上面代码修改为下面代码 wifi_config_t wifi_config { .sta {.ssid DEFAULT_ESP_WIFI_SSID, //WIFI的SSID.password DEFAULT_ESP_WIFI_PASS, //WIFI密码.threshold.authmode WIFI_AUTH_WPA…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
