公司最大的内卷,偷偷做单元测试

news2024/11/17 23:41:34

一位读者在看过我的《理解这八大优势,才算精通单元测试》后,问我:知道单元测试有好处,但实在没空写。看完文章后又想重新落实一下,有没有啥写好单元测试的技巧?

这位读者绝对不是第一个和我抱怨单元测试的人。这很好理解,中国互联网公司太多太卷,想要抢夺市场就要推出不同功能,而这些压力一部分落在了程序员身上,拼命赶需求。单元测试这种费力不讨好的事情,自然而然就没有人做。

就我多年的经验来看,写单元测试其实不会拖延项目,反而能够加快功能研发进度。单元测试的好处我就不在这里赘述了,只有真正尝试过的人才能理解。

马克·吐温曾说:“取得成功的秘诀就是开始”。本篇文章想和大家分享一下写好单元测试的技巧,希望可以给大家带来新方向。

单元测试技巧-1

一、单元测试的注意事项

单元测试是为了让我们快速查找并隔离损坏的代码片段。正因如此,这些函数和类在测试时不应该依赖于mock(模拟)和stub(存根)以外的其他元素。在测试中,如果试图覆盖的逻辑过于复杂,就难以确保覆盖的可靠性,也难以准确找出失败的原因。

因此,我们要注意单元测试包括以下几点。

01 简洁性

短函数更容易阅读和理解。我们每次只测试一个逻辑点,因此测试代码应该控制在几行之内。但如果是高级逻辑可能具有多个依赖项,这就需要大量样板代码来初始化模拟和存根。此外,单元测试同样适用DRY原则(Don’t repeat yourself,一次且仅一次),我们在写单元测试时要避免到处复制粘贴混乱的代码,最好使用组合而不是继承。

爱因斯坦曾说:“当你在生活中感到困顿时,也许是你把事情复杂化了。”所以,当我们对单元测试产生困惑时,也许是因为我们在单元测试中使用复杂的逻辑。注意一点:单元测试的目的在于测试代码,不要让单元测试本身也成为测试的一部分。

02 明确性

单元测试要使用详尽的长名称。这样的名称不仅能清楚表达信息,还能起到索引作用、快速定位相应测试。就算需求发生变化,我们只需要针对相应的测试进行更改,不必查看所有内容并检查受影响的内容。

好的单元测试一般只有一个断言,因此命名起来也很容易。例如,在处理金额计算时,it('should return 0 for an empty cart')要比it('works for 0') 或者 it('empty cart')好得多。对于使用函数名称作为测试名称的框架也是如此,shouldReturnZeroForAnEmptyCart就是一个很不错的的命名。

正如丁玲所言:“人生就像爬坡,要一步一步来。”单元测试也是如此,不要一次性测试整个方法,要一步一步来。 我们只针对单个需求写单元测试,代码就会变得易于阅读和维护。

03 可维护性

测试框架需要提供各种断言方法。它们提供不同的方法来检查结果,并且当断言失败时,它们还会显示更具体的错误消息,从而提供更多上下文来查看错误所在。

例如,

expect(result === expected).toBeTruthy();

将会失败

expect(received).toBeTruthy()
Received: false

尽管

expect(result).toBe(expected);

将提供更多有关具体失败原因的信息:

expect(received).toBe(expected) // Object.is equality
Expected: "John Doe"
Received: "JohnDoe"

框架还为不同的测试方式提供了各种断言。例如,在使用Jest进行测试时,toBe使用Object.is测试是否完全相等,而toEqualtoStrictEqual则深入比较对象,确保他们的类型和结构一致。

为了判断浮点数是否相等,我们需要采用一种特殊的匹配器,这种匹配器能够忽略由于浮点数在内存中的表示方式导致的微小舍入误差。在Jest中,匹配器是toBeCloseTo。虽然toEqual有时也能适用,但即使是看似简单的测试,如expect(0.1+0.2).toEqual(0.3)也可能无法通过。
单元测试技巧-2

二、单元测试的AAA原则

遵循AAA原则(Arrange、Act、Assert,安排、执行、断言),可以娴熟提升单元测试代码的清晰度、可靠性和可维护性。

第一步,安排阶段(Arrange)。 我们需要完成变量赋值、对象实例化对象以及测试运行所需的其余前置设置,并且定义预期结果。这样做的好处在于:一方面,我们需要在执行测试逻辑前就有明确预期;另一方面,这更方便在输入数据后立即查看预期输出,有助于避免代码混淆。

第二步,执行阶段(Act)。 我们将执行测试函数并存储其结果。结果存储其实是准备工作的自然延伸,有助于我们对结果进行回顾总结。

第三步,断言阶段(Assert)。 我们在这个阶段可以判断假设的正确性了。这正是单元测试的核心所在,因为这一环节实际上是对某些具体内容的测试。其目的在于是检查实际得到的结果否与预期结果相匹配。

我们要确保代码可靠性,避免错误输入、缺少参数、空数据、调用函数中的异常等情况的出现。代码覆盖率工具可以帮助我们查漏补缺,找到未测试的代码分支。我们要始终明确我们单元测试的目标,过于追求100%测试覆盖率反而会让单元测试代码越来越繁杂。这与《吕氏春秋》中的论点不谋而合:“不知轻重,则重者为轻,轻者为重矣。若此,则每动无不败”。

单元测试-3

三、单元测试的优化和维护

为了提高单元测试效率,我们需要模拟所有可能影响速度的外部依赖项,例如API调用、数据库或文件系统访问。我们在写单元测试时,应尽量避免线程休眠、等待和超时。如果必须设置超时,就应该将其缩短至几毫秒。在处理多线程或异步竞争条件时,精确控制出发条件比简单的等待要有效得多。

单元测试应当确保不会改变作用域外的任何内容。 如果测试仅在按照特定顺序执行时才能成功,这可能表明测试用例或测试代码存在问题。每个测试用例应独立运作。由于现代测试框架默认并行执行测试,因此我们不应依赖全局变量或之前测试的遗留效应。这也是全局变量常被视为不良编程习惯的原因之一,这会隐藏真正的依赖关系,导致代码耦合度升高,并在处理多线程问题时需要格外留意。

当测试需要复杂的重复配置时,应利用框架提供的设置和清理功能。这些功能保障了在每个测试用例或整个测试套件开始前后,相关代码能够得到执行。这样,无论是单独运行测试还是作为测试套件的一部分,都能确保测试结果的确定性,执行顺序不会对测试结果造成影响。

四、单元测试贵在坚持

《荀子·大略》:“夫尽小者大,积微成著,德至者色泽洽,行尽而声问远。”单元测试的作用只有经过长期积累才会变得显著。 其实,写单元测试更多的是对自己的代码负责。有测试用例的代码,别人更容易看懂,以后别人接手你的代码时,也可能放心做改动。

根据上述方法开始行动,单元测试也不是什么难事,毕竟“世上无难事,只怕有心人”。我发现关于单元测试有很多读者感兴趣,还有人曾问我单元测试到底该由测试进行还是开发进行。如果大家感兴趣,我也可以写一篇文章和大家简单分享一下。

*参考文章:Andriy Obrizan,How to Write Good Unit Tests: 14 Tips

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

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

相关文章

安卓窗口window无法移除屏幕外超过屏幕边界?-wms源码层面深入剖析

背景 学习了上一节的窗口位置变化相关的内容后,在窗口移动过程过程中发现有一个限制问题,大家可以看一下如下动态图: 已经尽力把窗口想要拖到屏幕外面,但是一直拖到不生效,只能在屏幕内部进行移动,这个到…

智能叮咚门铃的功能,开启未来家居安全新篇章

在科技日新月异的今天,智能家居产品正逐步渗透到我们生活的每一个角落,其中,智能叮咚门铃作为家庭安防与便捷生活的重要一环,正经历着前所未有的功能升级与变革。 一、高清夜视,全天候守护 全新智能叮咚门铃配备了高清…

芒果/充电桩系统云快充1.5底层协议源码(源码)

充电桩系统云快充1.5底层协议源码(源码) 介绍 云快充协议云快充1.5协议云快充协议开源代码云快充底层协议云快充桩直连桩直连协议充电桩系统桩直连协议 软件架构 1、提供云快充底层桩直连协议,版本为云快充1.5,对于没有对接过…

网上都是Python淘汰了!Python没用了!为什么都看不上Python?

最近,看到网上好多人站在在职程序员的角度去分析编程语言的一个优劣,劝小白学这个语言别学那个语言,这对小白来说是毫无意义的。 但是它又具有极强的一个误导性。 针对“Python没用了?马上就要被淘汰啦?为什么这么多…

8月22日笔记

解决centos7本地服务器刚安装之后yum install -y wget出现问题情况 首先网络能ping得通,然后就是yum命令会出问题,网上很多方法都是用wget命令来解决的,但是本身就没有wget,我怎么解决😅。还有就是改/etc/sysconfig/n…

推荐并整理一波vscode插件(哪些内置了,哪些好用)

文章目录 背景现在还在用的(21款)Chinese(Simplified)简体中文Chinese LoremLorem ipsumCode Runner(很推荐)Codeium: AI Coding Autocomplete(推荐)Draw.io IntegrationESLintHighlight Matching TagJavaS…

Window访问Linux目录权限问题

Linux 上已经安装 了 samba 服务,但有时会发现从window上无法打开一些目录,点击后没有反应也没有弹窗提示,如: 而且当用 sourceinsight 添加文件时,这些目录下也搜索不到任何文件,其原因是目录权限问题。注…

AI绘图 | Stable Diffusion教程,零基础上手(附最新最全安装包)

前言 通过Stable Diffusion技术,一个人可以毫不费力地实现令人惊叹的AI绘图,让创意和想象力跃然纸上。这项技术运用先进的深度学习模型,将简单的文字描述转化为精美绝伦的艺术作品。无需深厚的绘画功底或昂贵的设备,只需输入一段…

开放式耳机哪个品牌好?分享四款开放式蓝牙耳机排行榜前十名

我相信很多人都会有这些问题,不知道入手什么蓝牙耳机品牌、有线耳机不好收纳、有线耳机不方便携带、蓝牙耳机听歌的音质怎么样、蓝牙耳机是否会对大脑有危害、蓝牙耳机有什么品牌型号推荐以及想要不同价位的蓝牙耳机品牌推荐参考,okok问题也是很多&#…

【数据结构】关于快速排序,归并排序,计数排序,基数排序,你到底了解多少???(超详解)

前言: 🌟🌟Hello家人们,这期继续讲解排序算法的原理,希望你能帮到屏幕前的你。 🌈上期博客在这里:http://t.csdnimg.cn/g7PyB 🌈感兴趣的小伙伴看一看小编主页:GGBondlct…

每日OJ_牛客_因子个数(简单模拟)

目录 牛客_因子个数(简单模拟) 解析代码 牛客_因子个数(简单模拟) 因子个数__牛客网 解析代码 题意就是求一个数字的因子(>2的最小不能整除数字)个数:可以从最小因子2到数字的最大因子数&…

Git基础学习(二)

文章目录 一. Git方式的基本概念二. Git的使用方式三. Git的常规操作1. 创建版本库(本地仓库)2. 设置用户信息配置1> 查看git的配置列表a. 全局变量b. 局部变量c. 修改对应文件进行配置d. 有个别仓库需要配置成其他用户信息,可进入目标仓库所在文件,e…

Python 如何使用 itertools 模块

itertools 是 Python 中一个非常有用的模块,它提供了许多用于处理迭代器的函数工具。itertools 模块中的函数可以用于生成复杂的迭代器,以支持各种组合、排列和计数操作。 1. 什么是 itertools? itertools 是 Python 的标准库模块&#xff…

自闭症学校收多大儿童?让每个孩子都能获得关爱

在星贝育园,我们深知每一个自闭症儿童都是家庭的希望与未来,他们虽然面临独特的挑战,但同样值得拥有爱与关怀。因此,我们敞开怀抱,欢迎2至20岁的自闭症儿童加入我们的大家庭,让每个孩子都能在这里找到属于自…

腾讯优图开源多模态大模型VITA : GPT-4o的简易平替!

Abs:https://arxiv.org/pdf/2408.05211 Demo:https://vita-home.github.io/ Code:https://github.com/VITA-MLLM/VITA GPT-4o 的卓越多模态能力和用户交互体验在实际应用中非常重要,但没有开源模型在这两个领域同时表现出色。本文…

【c语言】整数在内存中的储存(大小端字节序)

整数在内存中的储存(大小端字节序) 1.整数在内存中的储存 2.大小端字节序 3.整数在内存中储存例子 4.字节序判断 5.死循环现象 文章目录 整数在内存中的储存(大小端字节序)整数在内存中的储存大小端字节序什么是大小端为什么会有…

TinaLinux NPU开发

MobileNet V2 MobileNet V2是一种轻量级的卷积神经网络(CNN)架构,专门设计用于在移动设备和嵌入式设备上进行计算资源受限的实时图像分类和目标检测任务。 以下是MobileNet V2的一些关键特点和创新之处: Depthwise Separable Co…

鸿蒙OS promptAction的使用

效果如下: import { promptAction } from kit.ArkUIlet customDialogId: number 0Builder function customDialogBuilder() {Column() {Blank().height(30)Text(确定要删除吗?).fontSize(15)Blank().height(40)Row() {Button("取消").onClick…

【中仕公考怎么样】2024下半年事业编联考冲刺!

多地下半年事业单位联考公告发布!11月2日笔试! 笔试时间:2024年11月2日(周六)上午。 08:30—10:00 《职业能力倾向测验》10:00—12:00 《综合应用能力》 考试科目: 综合应用能力(A类) 社会科学专技类(B类) 自然科学专技类(C类) 中小学教师类(D类) 医…

.[RestoreBackup@cock.li].SRC勒索病毒数据怎么处理|数据解密恢复

导言: 在数字化时代,信息技术的飞速发展极大地促进了社会进步与经济繁荣,但同时也为网络犯罪分子提供了前所未有的便利。近年来,勒索病毒作为一种新兴的网络威胁,正以前所未有的速度和规模肆虐全球,给个人…