当前位置: 首页 > 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…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...