最近在组里我又领了一个新任务:前端单元测试。
关于这个话题在很早的时候就想和大家聊了,奈何一直没机会。对于我个人来说,我是非常喜欢写单测的。最近还买了本《软件测试》的书,算是再次复习一下大学时学过的专业课,平时在捣鼓一些个人项目的时候也会做一些基础的单测。
一谈到单测,可能大家的第一反应都是敬而远之。
没啥用,没时间,我不会
我承认写单测是个非常有挑战性,且难度不小的活,但 我依然推荐大家尝试去写一写单元测试,因为它所带来的好处不仅仅是大家想的那么简单:“只是 Bug 少了一点”。所以,今天我会尝试从另外一些角度来讨论单测可以给我们带来哪些好处。
接着刚刚说到的 “只是 Bug 少一点” 这句话,可能大多数觉得单测就是在提测前减少一点 Bug 而已:
这样的想法确实是最直观的。但这只是想到了第一层,如果我们把 开发流程所有步骤 都加进来,会发现是这样的:
在 开发过程
后面,几乎每个流程都可能抛出 Bug。越是到后面流程才抛出的 Bug,程序员就越是要投入比开发阶段更大的时间和业务,而且所承受的风险也是最高的。
或许大家会想:不就改个 Bug,改几行而已。可是大家有没有想过在跟测的过程中,很可能你已经开始另一个需求的评审了! 此时的你在解决突然插入的 Bug 的时候,心态还会像刚开始写代码时候那么轻松么?
实际上,还有更多的隐性成本没有考虑,比如反复确认产品逻辑、反复确认交互设计、反复确认前后端接口设计、各端对产品的理解。 有的时候,你就会发现这样很魔幻的场景:明明是一个字段的展示问题,竟然要花上一上午,拉了 4、5 个人来开会核对的情况。
下面这张图,也在说明两个问题:一是 85% 的缺陷都在代码设计阶段产生;二是发现 Bug 的阶段越靠后,耗费成本就越高,呈指数级别的增长。这种 “指数成本” 的案例也经常发生,当我们改正一个 Bug 的时候,可能随之而来又会多出 3 个 Bug,俗称:改崩了。
所以,在早期的单元测试就能发现bug,不仅可以省时省力,在开发流程上提高效率,也能降低反复修改出现的风险和时间成本。
这一节主题就是大家经常想的:减少 Bug 率。我们不妨来想一个问题:什么才是 Bug? 相信所有开发人员都不愿意写 Bug,在 《软件测试》 这本书中将 Bug 描述成 “软件缺陷”,里面说道:
大多数的 “软件缺陷” 并非源自编程错误,对众多从小到大的项目进行研究而得出的结论往往是一致的,导致软件缺陷最大的原因是产品说明书!见下图
大多数的产品还是能够写出一份清晰明了的需求单的,奈何 ta 也不可能把所有情况想都枚举出来,这也导致了开发时很容易出现考虑不周全的情况。往往能够发现异常情况的人要么是测试、要么是交互视觉、要么是后期产品体验。 那到这个时候才发现的问题,然后再去修复又会出现的 指数爆炸的成本。
如果把实现功能看成走迷宫,把找到通路看成上线需求, 那么编码实现的过程就像从入口找出口,而单元测试则像从出口找入口。 这种开两个线程 “双向奔赴” 的找通路方法能够用最精准最快的方式找到通路。
单测所保障的不仅仅只是代码的正确性,毕竟大家在边开发边 Debug 的时候已经能验证 99% 的正确性了,而单测更大的地方在于 让我们不得不去思考到一些异常情况 ,这无形中就能增强代码的质量。
可能大家对上面这一节也不以为意,我能理解大家的侥幸心理。毕竟在公司里,开发写完 Bug,然后交给测试找出来是大家其乐融融表现。而且不写测试大家过得还挺好的,也没出什么大乱子。
造成这样的错觉在两个方面:一是测试找 Bug,开发再 Debug,这确实能解决燃眉之急,短期内很有效果。二是需求一直不断快速迭代,一期的 Bug,二期还能合着去改,二期改不了还有三期,三期结束了还有四期...... 。
这种永无止境的测试 + 开发模式能在一定程度上让我们的代码 “看起来是有保障的” 。
人肉测试固然好用,但是也有下面的缺点:
由于成本很高,人肉测试一般只会用来测业务功能,并没有太多测试资源可以分配到优化需求、技术需求上。所以对于这类需求只能通过前端开发人员自测,到目前为止也只是优化一个点,然后点点鼠标来自测,效率并不高。一旦优化过程中改出了问题,回滚、和修复的成本又会非常高,这也会助长大家 “不敢优化”、“能不动就不动” 的思想。
如果能有一定量的测试,则有足够强大的信心来支撑项目的优化,也有助于整个项目的未来发展和改进。
测试驱动开发(Testing-Driven Development)是敏捷开发中的一项核心实践和技术,也是一种设计方法论。
上面说的单测特点比较偏向于 “防守”,而 TDD 中的测试则偏向于 “进攻”。 TDD 的原理是在开发功能代码之前,先编写单元测试用例代码,在此基础上再补充产品代码。比如要实现 getUserById
这个服务,那么可以先写如下测试,然后再补充 getUserById
的实现:
describe('getUserById', () => {
it('可以根据 id 返回用户信息', () => {
// TODO: getUserById 未实现
const user = getUserById('122');
expect(user.id).toEqual('122');
})
})
这种方法在 Node 端非常实用。由于 Node 端要依赖的项非常多,比如数据库、各方接口、配置中心等等。每次用 Postman 去测接口,就会一次性将多个模块以及服务一起测了。如果别的服务还在开发或者有问题,就会直接阻塞了接口的开发。
虽然 Postman 在接口测试的时候很好用,但是它也有如下缺点:
单元测试则很好地填补了这一块,利用单测强大的 Mock 能力先将依赖项都 Mock 掉,开发时可以只关注某个函数、服务的开发,不会受其依赖项干扰:
由于每次提交代码都应该保证测试通过率 100%,所以我们也不会担心这些例子是否过期的问题。
测试用例还有个很好的功能:将使用案例记录在案。
很多时候别人写一些工具函数和方法,使用者是不能一眼就能学会怎么用的。往往这时写函数的人就会说:你看 XXX 文件就知道怎么用了。 但这些 “真实例子” 中通常会夹杂着很多依赖项,无法作用一个最小 Use Case 来理解。
而单测里的每个用例都可以看成一个最小的 example
,通过阅读 Test Case 就能马上知道这个函数怎么使用了。 这里举 redux 的 compose
函数的例子:
describe('Utils', () => {
describe('compose', () => {
it('composes from right to left', () => {
const double = (x: number) => x * 2
const square = (x: number) => x * x
expect(compose(square)(5)).toBe(25)
expect(compose(square, double)(5)).toBe(100)
expect(compose(double, square, double)(5)).toBe(200)
})
})
}
就算我们不知道 compose
是用来干嘛的,但是我们很清楚地知道,使用方法就是从右到左地执行回调。
由于每次发布时我们都要保证单测 100% 通过率,所以永远不用担心这个 Use Case 无法使用、过期的问题。
抛开这些项目质量、优化流程的原因,推荐大家写单测的另一重要原因就是 提升个人能力。
几乎所有 Jest 的入门文章的开头都会有一个非常简单的 Test Case:
expect(1 + 1).toEqual(2)
这很容易让人误以为单测很简单,以为不就是学一个框架那样嘛。然而,只有在真正编写测试用例的时候才会发现单测的难度呈指数级上涨。因为测试的本身是另一个领域,是需要通过不断练习才能掌握测试技巧的。 对前端单测来说,它的难度包括但不限于如下几点:
localStorage
,cookie
这些浏览器独有的东西时,Jest 就会报错,很多人受不了直接放弃了@nestjs/testing
,React.js 有 react-testing-library
。有的库 Redux 又会有自己独特的 testing guide总的来说,写单测并不像大家想的这么简单,jest
只是个开始的地方。不过,从另一个角度来看,如果你能坚持写好单测,对个人能力也大有裨益:
稍微总结一下,单测可以在 优化开发流程、保证项目质量、给项目优化上保险、驱动开发、提供 Use Case、提升个人能力 方面有着非常大的益处。
当然,本文也并非要让大家马上给项目上单测,只是希望大家能够多尝试自己领域之外的东西,不要固步自封。对个人而言,多练习写单测能力肯定是好处多于坏处。
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/udhMtManyS5u21YhxP2qYA
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。