【Rust自学】11.1. 编写和运行测试

发布时间:2026/11/9 7:39:39

【Rust自学】11.1. 编写和运行测试 11.1 编写和运行测试11.1.1. 什么是测试在Rust里测试就是一个函数用于验证非测试代码的行为是否符合预期。一个测试函数通常执行三个操作- 准备(Arrange)数据/状态- 运行(Act)被测试的代码- 断言(Assert)结果这三个操作在有些语言里叫3A步骤。11.1.2. 解剖测试函数测试函数本质上仍然是一个函数不同之处在于它必须用test属性(attribute)进行标注。Attribute就是一段Rust代码的元数据。它不会改变被它修饰的代码的逻辑只是对代码进行修饰或者说标注。实际上在 5.2. struct使用例加打印调试信息 中就已经用到过。在函数上加#[test]就可以把函数变为测试函数。11.1.3. 运行测试先不管测试函数内的内容编写完测试函数之后如何运行它呢使用cargo test命令来运行所有测试。这个命令会构建一个测试运行器(test runner)可执行文件。它会逐个运行标注了test的函数并报告它们是否成功。当使用Cargo创建library项目时会生成一个test module里面有一个现成的test函数可以参照它来编写其他测试函数。实际上你可以添加任意数量的test module或test函数。看个例子创建一个名为adder的新库项目$ cargo new adder --lib Creating library adder package note: see more Cargo.toml keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html $ cd adder打开项目lib.rspub fn add(left: usize, right: usize) - usize { left right } #[cfg(test)] mod tests { use super::*; #[test] fn it_works() { let result add(2, 2); assert_eq!(result, 4); } }之所以这是一个测试函数是因为它被#[test]标注了而不是因为它位于test模块中。test模块里也可以包含普通函数。使用cargo test来运行测试$ cargo test Compiling adder v0.1.0 (file:///projects/adder) Finished test profile [unoptimized debuginfo] target(s) in 0.12s Running unittests src/lib.rs (target/debug/deps/adder-302521ba8d0f0bdf) running 1 test test tests::it_works ... ok test result: ok. 1 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分析一下这个输出- 首先是编译(Compiling)、完成(Finished)和运行(Running)。- 接下来是running 1 test表示正在执行一个测试。下一行显示这个测试是tests::it_works结果是ok。这个项目只有一个测试但如果有多个测试cargo test会全部运行。- 然后是test result: ok.表示项目中的所有测试都通过了。具体来说1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out表示1个通过、0个失败、0个被忽略、0个基准测试、0个被过滤掉。-Doc-tests adder指的是文档测试的结果。Rust能够编译出现在API文档中的代码这有助于保证文档始终与实际代码保持同步。如果把函数改名输出哪里会变呢pub fn add(left: usize, right: usize) - usize { left right } #[cfg(test)] mod tests { use super::*; #[test] fn exploration() { // 改名为 exploration let result add(2, 2); assert_eq!(result, 4); } }输出$ cargo test Compiling adder v0.1.0 (file:///projects/adder) Finished test profile [unoptimized debuginfo] target(s) in 0.08s Running unittests src/lib.rs (target/debug/deps/adder-302521ba8d0f0bdf) running 1 test test tests::exploration ... ok test result: ok. 1 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可以看到测试名从tests::it_works变成了tests::exploration。11.1.4. 测试失败测试函数一旦触发panic!测试就失败。由于每个测试都在自己的线程中运行主线程会监视这些线程。当主线程看到某个测试因触发panic!而崩溃时那个测试就会被标记为失败。看个例子pub fn add(left: usize, right: usize) - usize { left right } #[cfg(test)] mod tests { use super::*; #[test] fn exploration() { let result add(2, 2); assert_eq!(result, 4); } #[test] fn another() { panic!(Make this test fail); } }这个another函数直接调用了panic!。运行一下看结果$ cargo test Compiling adder v0.1.0 (file:///projects/adder) Finished test profile [unoptimized debuginfo] target(s) in 0.08s Running unittests src/lib.rs (target/debug/deps/adder-302521ba8d0f0bdf) running 2 tests test tests::exploration ... ok test tests::another ... FAILED failures: ---- tests::another stdout ---- thread tests::another (448960) panicked at src/lib.rs:17:9: Make this test fail note: run with RUST_BACKTRACE1 environment variable to display a backtrace failures: tests::another test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s error: test failed, to rerun pass --libtests::another失败了而tests::exploration仍然是ok。失败原因是thread tests::another panicked at src/lib.rs:17:9意思是在src/lib.rs的第17行第9列触发了panic!也就是源代码中写该宏的位置。总结一下test result: FAILED表示整体测试运行失败。更具体地说是1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out。
延伸阅读

更多相关文章

2026/11/8 6:30:32

【Rust自学】11.2. 断言(Assert)

11.2 断言(Assert) 11.2.1. 使用assert!宏检查测试结果 assert!宏来自标准库,用于判断某个条件是否为true。它接收一个返回类型为布尔值的表达式: - 当assert!内的值为true时,测试通过,assert!也不会做多余的操作。 - 当assert!…

2026/11/7 3:10:03

mpweixin 微信打卡小程序

一、关键词微信打卡、积分兑换、打卡排行、惩罚措施、社交论坛二、作品包含源码数据库全套环境和工具资源本地部署教程三、项目技术前端技术: Html、Css、Js、Vue2.6、Element-ui、uniapp后端技术:Java、SpringBoot2.2.2、MyBatis-Plus四、运行环境&…

2026/11/7 10:20:55

【Rust自学】4.2. 所有权规则、内存与分配

4.2 所有权规则、内存与分配 4.2.0 写在正文之前 在学习了 Rust 的通用编程概念后,就来到了整个 Rust 的重中之重——所有权。它跟其他语言都不太一样,很多初学者觉得学起来很难。这个章节就旨在让初学者能够完全掌握这个特性。 本章有五小节&#xf…

2026/11/9 7:38:44

宁夏高压电工证怎么考 上岗必备全攻略

宁夏高压电工证怎么考 上岗必备全攻略 你还在为找不到电工工作发愁?宁夏高压电工证成了很多电工求职者的“硬门槛”。别再观望了,现在考证还不算晚。本文从零开始,带你一步步了解宁夏高压电工证怎么考,让你早日拿到上岗必备的证书,顺利入职。…

2026/11/9 7:38:44

南庄电工证真实经历:全流程办理避坑指南

南庄电工证真实经历:全流程办理避坑指南 你是不是也像我一样,刚开始准备考南庄电工证的时候,四处打听,怕被中介坑,连报名都找不到靠谱的渠道?今天我就从自己的真实经历出发,告诉你怎么一步步把南庄电工证拿下来,不走弯路、不花冤枉钱。…

2026/11/9 7:38:44

电工证口试技巧怎么掌握?考前押题帮你少走弯路

电工证口试技巧怎么掌握?考前押题帮你少走弯路 实操考试心里没底怕挂科?电工证口试技巧掌握不到位,直接影响考试结果,尤其在考前复习阶段,很多人会陷入“刷题无效”“知识点记不住”的困境。尤其是像郑州这样的城市,电工证报考人数逐年攀升,竞争压力也…

2026/11/9 7:38:44

工厂电工作业图片高清怎么报名不被中介坑

工厂电工作业图片高清怎么报名不被中介坑 你是不是也在为“ 工厂电工作业图片高清 怎么报名”发愁?网上一搜全是中介电话,怕被坑,又不知道从哪入手?其实,只要掌握正确的方法,报名特种作业证一点都不难。下面我结合 开封中小施工企业负责人…

2026/11/9 0:37:55

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/9 0:03:09

建设厅的特种工有哪些含金量高?别交完钱考不过

建设厅的特种工有哪些含金量高?别交完钱考不过 怕考不过白交培训费?别急,先搞清楚建设厅的特种工有哪些含金量高的证,再决定是不是值得投入时间和金钱。 建设厅的特种工证是建筑行业里最基础、也最实用的证书之一,涉及多个作业类别,每种证的 含金量…

2026/11/9 0:03:09

荆门市电工证报名怎么考才靠谱 全国通用证别交冤枉钱

荆门市电工证报名怎么考才靠谱 全国通用证别交冤枉钱 怕考不过白交培训费?荆门市电工证报名前必须知道这些避坑指南。别看网上一堆培训机构广告,真要报个电工证,很多人被坑得一塌糊涂。特别是那些打着“包过”旗号的,最后不是考试不过,就是证不是全国通…

2026/11/9 0:03:09

高空电工作业过程通过率揭秘:怎么选靠谱机构不被坑

高空电工作业过程通过率揭秘:怎么选靠谱机构不被坑 不知道去哪报名怕被中介坑?你不是一个人。现在特种作业证报名渠道五花八门,从线下培训机构到线上代理,真假难辨。尤其是像高空电工作业这类高风险、高门槛的作业类型,证书含金量和考试通过率直接影响你…

2026/11/9 6:30:27

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/7 14:50:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑