当前位置: 首页 > news >正文

优测云测试平台 | 有效的单元测试(下)

接着上一篇内容,我们继续~

四、测试的目标之三:快速反馈

测试的快速反馈有两个方面的含义:

  • 1.测试运行要快速出结果。

  • 2.当测试失败时,要能快速定位失败原因。

测试运行效率决定了开发的工作周期运转的快慢。在理想的 TDD 模型中,开发人员一遍又一遍地重复着“测试 -> 实现 -> 测试“ 这样的周期循环,直到所有用例通过。持续集成和持续交付的过程也是如此。不管是单元测试还是大型测试,运行效率都是应该追求的目标。

同样在的道理,当测试出现用例失败时,如果我们要花很长的时间来定位到原因,也会拖慢我们从“测试”到“实现”的速度。要提高快速定位的能力,一方面要提高被测代码的可观测性,另一方面要给用例合理命名,还有在断言时加入有价值,易读易懂的 message. 在去年的一次分享中,已经提到过如何建设被测系统的可观测性并且做了一些支撑工具。在用例命名和断言信息方面,越是大型测试要求越高,因为其所覆盖的代码范围广,失败节点多,而在单测中则相对要求低一些,因为其被测代码覆盖范围小,相对容易定位。

但是!在单元测试时依然要认真给用例命名,充分添加断言信息。这一建议单独另起一段,考虑的是当我们写单测时的心智问题。不少开发在写单测时多心智是:“单测是写给我自己看的,这个用例测试的是我负责的代码,出了问题我很快就知道定位”,但是从团队和业务的角度出发,测试都是写给整个开发团队看的,这与代码的 readability 是一样的。code for team, test for team! 测试用例怎样命名,断言信息写些啥,有很多博客和问答可以提供参考.这里提供一个建议:在命名和添加断言信息时,想象着它们在报告中是如何显示的。以下用一个实际的例子来对比一下断言信息好坏的明显区别。
用例 v1

func TestQueryRecentExecs(t *testing.T) {t.Run("count 100 is too large", func(t *testing.T) {proxy := clientProxy()ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*5)defer cancelFunc()req := &caselog.QueryCaseRecentExecsRequest{CaseId: 5,Count:  100,}_, err := proxy.QueryCaseRecentExecs(ctx, req)require.Error(t, err)assert.Equal(t, errs.ErrorTypeBusiness, trpcErrType(err))})
}

该用例中,被测接口要求入参中

Count

不能大于等于 100,我们向被测服务发起异常参数的请求,期望其返回业务类型的错误(不能返回框架类型的错误,框架类型的错误是诸如服务寻址失败,超时之类的,跟业务无关的错误,具体参考 trpc 错误手册)。某次运行用例失败后得到的 log 如下:

test log v1

Failed
=== RUN   TestQueryRecentExecs/count_100_is_too_largecaselog_test.go:56: Error Trace:  caselog_test.go:56Error:        Not equal: expected: 2actual  : 1Test:         TestQueryRecentExecs/count_100_is_too_large--- FAIL: TestQueryRecentExecs/count_100_is_too_large (2.00s)

从这个错误信息中,我们从用例名中知道目的是验证

Count

值为 100 过大而产生错误,但是在错误信息中我们读到的是“因为我们期望 2 而实际值为 1,用例失败”。这里 2 和 1 分别是什么?没有信息。

下面进行一版改进:

用例 v2


func TestQueryRecentExecs(t *testing.T) {t.Run("large count 100 cause biz error", func(t *testing.T) {proxy := clientProxy()ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*5)defer cancelFunc()req := &caselog.QueryCaseRecentExecsRequest{CaseId: 5,Count:  100,}_, err := proxy.QueryCaseRecentExecs(ctx, req)require.Error(t, err)assert.Equal(t, "business", trpcErrTypeName(err), "unexpected trpc error type")})
}

test log v2

Failed
=== RUN   TestQueryRecentExecs/large_count_100_cause_biz_errorcaselog_test.go:80: Error Trace:  caselog_test.go:80Error:        Not equal: expected: "business"actual  : "framework"Diff:--- Expected+++ Actual@@ -1 +1 @@-business+frameworkTest:         TestQueryRecentExecs/large_count_100_cause_biz_errorMessages:     unexpected trpc error type--- FAIL: TestQueryRecentExecs/large_count_100_cause_biz_error (0.81s)

v2 中很明确,trpc error type 与预期不符,预期是 business 而实际值为 framework. 这是一个接口测试,出现 Framework error 通常是被测服务没有正确部署或者测试流水线所在网络环境与被测服务不通。(用例中使用 testify 断言,其断言格式固定,可能不一定是最好的格式,略显啰嗦,但是它在其他方面比较方便,为了整个项目统一我们只能“因地制宜”。更简洁的断言信息是

t.Errorf("QueryCaseRecentExecs response error type mismatch got = %s, want = %s", trpcErrTypeName(err), "business")

即使该用例不是我写的,只要具备基本的 trpc 背景知识,看到报告后第一反应就是去确认被测服务是否健康,以及流水线网络环境是否正确,而在 v1 中,我可能还得打开 ide 查看一下用例代码,看用例代码还只能知道不是 business 错误,实际是什么错误并不知道,还得跳转到 trpc 的源代码才知道 1 是 framework 错误。(还有另一种错误是 “callee framework”)。孰快孰慢一目了然。

五、测试的第四个目标:用例集的可维护性

  • 1.功能代码有可读性要求,测试代码也有,同样,功能代码有可维护性要求,测试代码也有可维护性要求。可维护性最佳实践与功能代码是相通的,仅举几例:
    DRY, 以提取函数/提取常量来替代复制粘贴。

  • 2.以配置代替写死值,可以参考一些 go 的标准库里面单元测试的方法,可以在测试时指定 flag,在用例中 parseFlags 来读取配置。

  • 3.不要滥用设计模式,测试代码复杂度不宜过高,否则我们是否还有给测试代码写测试代码?
    参考阅读
    《Unit Testing: Principles, Practices, and Patterns》

脚注
[1]覆盖率并不一定是越高越好,对于没有测试价值的,低风险的代码,强行覆盖会消耗过多的时间和精力。怎样定一个覆盖率红线是另一个话题,长话短说就是代码库的 owner 自行决定才是最科学的。

[2]那些单元测试已经充分测试过的逻辑,无需在接口测试和端到端测试中重复。
优测测试平台简介:
是一个为企业与开发者提供专业的测试工具和服务的平台,沉淀十年产品测试经验,提供终端测试、接口测试、性能测试、安全测试等多领域测试服务与产品,协助客户提高效率降低成本,保证产品质量。

相关文章:

优测云测试平台 | 有效的单元测试(下)

接着上一篇内容,我们继续~ 四、测试的目标之三:快速反馈 测试的快速反馈有两个方面的含义: 1.测试运行要快速出结果。 2.当测试失败时,要能快速定位失败原因。 测试运行效率决定了开发的工作周期运转的快慢。在理想的 TDD 模型中&#x…...

CUDA安装

在cmd中输入nvidia-smi。显示CUDA Version:12.3,所以只能下载小于等于12.3的版本。如下图: 进这个网址:https://developer.nvidia.com/cuda-toolkit-archive 选择一个版本下载。 选择完后之后这样选择: 最后点击下载即…...

【XTDrone Ubuntu18.04】XTDrone + Ubuntu18.04 + PX4 安装过程

重新配置所有的软件 卸载之前安装的ROS GAZEBO 记得把/home下的.ros和.gazebo也删除,删就删干净 参考链接:ROS的卸载与安装 血泪总结!亲测有效 卸载ROS方法 正式安装 安装依赖 sudo apt install ninja-build exiftool ninja-build protobuf…...

网站使用什么协议比较好

网站协议大多数使用HTTP和HTTPS HTTP协议,超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议。 HTTP是应用层协议,同其他应用层协议一样,是为了实现某一类具体应用的协议&…...

18. 机器学习——集成学习

机器学习面试题汇总与解析——集成学习 本章讲解知识点 什么是集成学习AdaBoost梯度提升树(Gradient Boosting Decision Tree, GBDT)随机森林(Random Forest,简称RF)XGBoostLightGBM本专栏适合于Python已经入门的学生或人士,有一定的编程基础。 本专栏适合于算法工程师、机器…...

SimaPro生命周期评估建模与碳足迹分析流程

SimaPro以系统和透明的方式轻松建模和分析复杂的生命周期,通过确定供应链中每个环节的热点,从原材料的提取到制造,分销,使用和处置,衡量所有生命周期阶段的产品和服务对环境的影响。SimaPro是过去25年评估生命周期的最…...

我的项目分享(不喜勿喷)

我要分享的项目是大喇叭C2C电商平台系统,一个面向移动端的电子商务平台,为个体消费者和商家提供直接交易和沟通的便利,丰富了人们的生活。 主要功能模块: 该项目的主要功能包括: 1. 用户注册功能:使用正则…...

PyTorch:张量与矩阵

PyTorch 是一个基于 Python 的科学计算包,专门针对深度学习研究,提供了丰富的工具和库。在 PyTorch 中,张量(tensor)是深度学习的核心数据结构,它可以看作是可以进行自动微分的多维数组。张量不仅可以代表标…...

传统广电媒体为何选择上云?有何优势?

随着现在互联网和科技的发展,现在更多的行业都搭上了科技这辆快车快速的完成了转型,那么在传统的广电媒资行业他们目前有哪些痛点呢?传统广电媒体转型发展现状是什么?企业如何数字化转型?企业上云的优势有哪些&#xf…...

系列十、堆参数调优

一、堆内存调优参数 -Xms堆空间的最小值,默认为物理内存的1/64-Xmx堆空间的最大值,默认为物理内存的1/4-XX:PrintGCDetails输出详细的GC处理日志 二、获取堆内存的默认物理内存 /*** Author : 一叶浮萍归大海* Date: 2023/11/16 14:50* Description: 获…...

sqlite3简单使用

为什么要使用sqlite3? sqlite3轻量简介,无需单独的数据库服务,只需访问磁盘上的.db的文件。在某些情况下很有用。 下面是一些简单的使用代码: import sqlite3 from uuid import uuid1# 连接数据库文件,如果不存在会创建 with…...

实测文心一言4.0,真的比GPT-4毫不逊色吗?

10月17日,李彦宏在百度世界2023上表示。当天,李彦宏以《手把手教你做AI原生应用》为主题发表演讲,发布文心大模型4.0版本。 今天,咱们就开门见山啊。这一回要测一测,昨天才发布的文心一言大模型 4.0。 之所以要测它&…...

损失函数——KL散度(Kullback-Leibler Divergence,KL Divergence)

KL散度(Kullback-Leibler Divergence,简称KL散度)是一种度量两个概率分布之间差异的指标,也被称为相对熵(Relative Entropy)。KL散度被广泛应用于信息论、统计学、机器学习和数据科学等领域。 KL散度衡量的…...

基于springboot的医护人员排班系统 全套代码 全套文档

基于springboot的医护人员排班系统,springboot vue mysql (毕业论文10411字以上,共27页,程序代码,MySQL数据库) 代码下载链接:https://pan.baidu.com/s/177HdCGtTvqiHP4O7qWAgxA?pwd0jlf 提取码:0jlf 【运行环境】 IDEA, JDK1.8, Mysql, Node, Vue …...

【YOLOX简述】

YOLOX的简述 一、 原因1. 背景2. 概念 二、 算法介绍2.1 YOLOX算法结构图:2.2 算法独特点2.3 Focus网络结构2.4 FPN,PAN2.5 BaseConv2.6 SPP2.7 CSPDarknet2.8 YOlO Head 三、预测曲线3.1 曲线 一、 原因 1. 背景 工业的缺陷检测是计算机视觉中不可缺少…...

一文带你深入浅出Web的自动化测试工具Selenium【建议收藏】

文章目录 前言第01节 Selenium概述第02节 安装浏览器驱动(以Google为例)第03节 定位页面元素1. 打开指定页面2. id 定位3. name 定位4. class 定位5. tag 定位6. xpath 定位7. css 选择器8. link 定位9. 示例 有道翻译 第04节 浏览器控制1. 修改浏览器窗…...

Django模版层

解析: forloop内置对象:运行结果解析 counter0: 从0开始计数 counter : 从1开始计数 first: True,判断循环的开始 last : Tues,判断循环的结束模版变量的书写 我们可以在html中编写python代码。 演示: {{ 填写变量 }}{% 填写类的 %}{{ d.0 }} {{ d.1 }…...

同一个IP地址可有不同的写法?

每个人在上网的时候,都会被分配一个IP地址,这是互联网世界中的“身份证号码”。IP地址是以数字形式呈现的,例如192.168.1.1。然而,你是否知道,尽管一个IP地址的数字串唯一标识一个设备,但它可以有不同的写法…...

《Effective C++》条款13

以对象管理资源 有这样一段代码: class A { public:A* create(){...}}; class B :public A { public:A* ptr create();...delete ptr; }; 我们定义了ptr去接收create()函数的返回值,并且在最后进行了回收资源。看似是没问题的。但是实际上有很多隐患&am…...

【入门Flink】- 09Flink水位线Watermark

在窗口的处理过程中,基于数据的时间戳,自定义一个“逻辑时钟”。这个时钟的时间不会自动流逝;它的时间进展,就是靠着新到数据的时间戳来推动的。 什么是水位线 用来衡量事件时间进展的标记,就被称作“水位线”&#x…...

华为交换机的基本配置,看完秒懂

一、 交换机的基本配置 交换机连接方式 本地&#xff1a;计算机COM口/USB口 --> Console线 --> 交换机Console口 远程&#xff1a;Putty、SecureCRT、Xshell远程管理工具 华为VRP网络操作系统 1&#xff09;华为的视图模式 <Huawei> //用户视图&#x…...

spark与scala的对应版本查看

仓库地址 https://mvnrepository.com/artifact/org.apache.spark/spark-core 总结 spark3.0 以后&#xff0c;不再支持 scala2.11spark3.0 以后&#xff0c;只能用 scala2.12以上...

影响力|子芽首创代码疫苗技术获评“年度技术突破者”

近日&#xff0c;由业界权威机构嘶吼产业研究院主办的2023网络安全“金帽子”年度评选结果已正式公布。本届评选由网安产业监管机构及相关委办局领导坐镇、行业资深专家、头部网安企业负责人权威加持。凭借首创的专利级代码疫苗技术创新突破了数字供应链安全领域关键核心技术&a…...

还在为忘记BIOS密码担心?至少有五种方法可以重置或删除BIOS密码

忘记密码是一个我们都非常熟悉的问题。虽然在大多数情况下,只需单击“忘记密码”选项,然后按照几个简单的步骤即可恢复访问权限,但情况并非总是如此。忘记BIOS密码(通常为避免进入BIOS设置或避免个人计算机启动而设置的密码)意味着你将无法完全启动系统。 幸运的是,就像…...

部署百川大语言模型Baichuan2

Baichuan2是百川智能推出的新一代开源大语言模型&#xff0c;采用 2.6 万亿 Tokens 的高质量语料训练。在多个权威的中文、英文和多语言的通用、领域 benchmark 上取得同尺寸最佳的效果。包含有 7B、13B 的 Base 和 Chat 版本&#xff0c;并提供了 Chat 版本的 4bits 量化。 模…...

java面试常问

文章目录 java 基础1、JDK 和 JRE的区别2、 和equals的区别3、String、StringBuffer、StringBuilder4、String str “a”、 new String(“a”)一样吗&#xff1f;5、ArrayList 和 LinkedList的区别&#xff1f;6、HashMap的原理与实现6.1、容量与扩容6.2、扩容机制 7、HashMa…...

关于nginx一个域名,配置多个端口https的方法

假如我有一个域名 abc.com。在这个域名下&#xff0c;部署了两个应用&#xff0c;分别对应端口&#xff1a;8081&#xff0c;8082 想要给两个应用接口都开启https访问。 nginx配置如下&#xff1a; server { #监听443端口 listen 443 ssl;…...

IntelliJ IDEA插件开发入门实战

介绍 IntelliJ IDEA是备受赞誉的Java开发工具&#xff0c;提供了丰富的功能和工具。通过使用插件&#xff0c;可以扩展和增强这个集成开发环境。IntelliJ IDEA拥有庞大的插件生态系统&#xff0c;涵盖了代码分析、格式化工具和完整的框架等各个领域。开发人员还可以创建自己的…...

站群服务器如何选择

站群服务器如何选择 1.站群服务器线路 双线服务器在访问网站不受线路影响&#xff0c;较稳定。 2.站群服务器的稳定性 选择站群服务器的时候&#xff0c;服务器的稳定性是非常重要的。 3.站群服务器带宽大小 站群服务器网站在日常使用时&#xff0c;主要的目的是为了集中网…...

【vue】AntDV组件库中a-upload实现文件上传:

文章目录 一、文档&#xff1a;二、使用(以Jeecg为例)&#xff1a;【1】template&#xff1a;【2】script&#xff1a; 三、效果图&#xff1a; 一、文档&#xff1a; Upload 上传–Ant Design Vue 二、使用(以Jeecg为例)&#xff1a; 【1】template&#xff1a; <a-uploa…...