对于前端测试的一点杂谈

之前本来在 12 月就应该写这一篇文章的,大致是同事需要做 SDK 开发,我要求必须要有对应测试,但对于怎么去设计测试比较迷茫,本来早在 19 年就写过一篇如何构造一些有意义的测试,但从某种角度来说这更偏后端一些,对于前端的测试来说有一些不同 。
然后被裁了,本来不想写了,但之前帮做模拟面试以及被面试时其实都有提到一些内容,所以这里简单谈下我对前端测试的一些看法 。
新读者注意:本人屁话较多,不喜勿喷,上角点叉 。(我好脆弱啊哥哥.jpg)
什么时候我们需要测试
如果你的回答是:「当然是什么时候都需要测试」——那么恭喜你,你还没有接受过现实排期和业务的毒打(这里指的是国内互联网的情况) 。
理想情况下,我们当然希望「都有测试,测试覆盖率达到 100%」,但是现实往往无法支撑起这个美好的愿景 。
在这种情况下我们在什么时候选择编写测试代码呢?比较核心的几个点是:
核心、高风险业务内容,比如我 19 年写的文章就是针对支付、会员、订单这一块的后端服务进行的大规模覆盖基础能力提供方,比如基础设施、通用基建,包括本文引子部分的 SDK对于前端来说基础组件也是可以作为测试的项
【对于前端测试的一点杂谈】其实从上面我们就可以看出,除了核心业务是为了止损外,大部分可以优先写测试的部分都是因为整体需求开发相对可控,不至于朝令夕改,同时作为基本盘,服务人数众多,牵一发而动全身,一个 Bug,全家完蛋 。
当然实际上很多公司处于 0 测试的状态推进,包括之前在 B 站时我使用的一些内部工具,其实也是没有测试或者是测试覆盖率低的状态 。因此也确实在其中埋了不少隐患 。
出于大部分公司的迭代速率和需求的不稳定性,对于业务做一些集成测试性价比不高,更多的是如果你有闲心可以给自己的 utils 方法做一些测试 。
当然,如果业务稳定、排期宽松,那毫无疑问可以达到你想要的效果 。
测试覆盖率
在 19 年的文章中实际上就有关于测试覆盖率的描述,在这里再次重申下,测试需要追求覆盖率,但不要追求覆盖率 100% 。
这一点在这次面试中也和面试官讨论过(似乎不止一位),如果没有测试覆盖率指标,那么测试将毫无意义,因为每个人都可以以各种理由偷懒不做测试;但如果过分追求数字,接下来面对的可能是更灾难性的结果:
在个人(开源)项目中自然是想怎么玩都可以的,但在企业开发中我们往往会遇到时间与健壮性的平衡,大部分老板其实只关注「快糙猛」,你先帮我把第一版推上去,剩下的我们之后再说 。如果在这种情况下过分追求覆盖率,基本相当于没有人性的强行军,可以先顶一个小目标,比如 80% 覆盖率,而不是 90%-100% 。
因为喊个口号容易,但当你实际开始写测试就会发现,要完美覆盖你的 case 而不是只在乎数字的情况下,写测试的时间将是开发时间的 1.5-3 倍,而且是随着覆盖率指标上升指数级上升的,也就是说——有一些犄角旮旯的地方它就是不太好搞,也就是「搞的性价比不高」 。
当然如果这些不好搞的地方是核心内容,那就是不得不搞了,这种时候其实更偏向于一劳永逸,也是一种高性价比的投入,这是另一回事 。
测试有什么用途
这话说的仿佛是一个废话,你可能会说「测试嘛,当然是为了测试」 。但实际上测试为我们提供了以下便利:
实际上一个最简单的集成测试本身就是一个 Quick Start,可以直接贴测试用,而我们通常会同时加上注释,巧了,代码的可读性又上升了 。
当然这里偶尔也会遇到让人无语的情况:接受的同学改代码连带着测试一起改了——可能是另一种正确吧 。建议大家动测试之前一定要看清楚测试代码的含义和价值 。
前端的测试
后端的测试在文章开头已经有传送门了,本文重点还是说下前端的测试,常见的测试还是单元测试和集成测试 。
这里以埋点库 SDK 为例,因为 UI 业务上的单元测试发挥空间比较有限,相对的费力不讨好一些,前端 SDK 的 case 更典型(简单)且全面 。
单元测试
说起单元测试,我们最先想到的肯定是 jest,老牌测试了,关于怎么使用可以看官方文档和各种文章,这里跳过这一趴;此外,我们最后的遗作 SDK 已经使用了,理论上应该是比 jest 更好用一些的 。
目录结构来说可以是一个 src 文件对应一个 test 文件,这样更加一目了然一些:
├── src│├── index.ts│├── trackers││└── web││├── click.ts││├── expose.ts││└── pv.ts│├── typings││└── window.d.ts│└── utils│├── buvid.ts│├── format.ts│├── http.ts│└── utils.ts├── test│└── unit│├── index.test.ts│├── trackers││└── web││├── click.test.ts││├── expose.test.ts││└── pv.test.ts│├── tsconfig.json│└── utils│├── buvid.test.ts│├── format.test.ts│└── utils.test.ts
这里有几个值得讨论的点:
首先是我们是否要使用 TDD,TDD 是一个非常老的话题,甚至早在我还没工作的时候就写过一篇文章(2016 年,看看得了,勿挖坟):Node.js 用Mocha+Chai做单元测试 入门,但是在实际工作中碍于文章开头提到的原因,我们很少去真正使用完全的 TDD(在后端测试时我有用过,因为这是明确必须测试的,剩下的情况下都可能会受到迭代排期影响),大部分情况下我们更多的开发思路还是:
我的库需要提供哪些能力这些能力怎么拆分成函数(尽量无副作用)挨个覆盖我的函数对于想到的边缘 case 进行填补

对于前端测试的一点杂谈

文章插图
单元测试最难的部分可能是要挨个 mock 你需要的部分,同时为了避免干扰,建议少用全局变量、多写无副作用函数,能让你的开发之旅顺利很多 。
对于大部分基建项目来说,单元测试是一件性价比相当高的方式,非常建议大家抽空做一波 。(当然,很容易 mock 麻了,比如我卷到最后就卷不下去了,要 mock 太多东西了) 。
集成测试
上面说了半天,其实对于单元测试来说,前后端并没有太大区别,前端 mock 浏览器、网络 IO;后端 mock 网络 IO、底层依赖、文件存储,本质上都是 mock + 对函数进行测试 。
对于集成测试来说就更为痛苦,在这里我们努力的使用,如果说单元测试测的是函数,那么集成测试测的就是能力,简化一下上面在单测中介绍的思路:
我的库需要提供哪些能力用代码怎么实现覆盖我设计的能力对于想到的边缘 case 进行填补
可以说,如果单元测试还是要你具体代码拆分后再进行测试的设计,那么集成测试从一开始就可以进行设计了——毕竟在系统设计阶段,你已经会敲定「我会提供什么」了 。
剩下的可能就是漫长而痛苦的 mock 阶段,甚至你可能需要准备好一个去承载你的测试页面 。
总结
对于大部分刚开始写测试的工程师来说,卡点可能更多的在于怎么去取舍和怎么去设计我的测试用例,这里简单的提供一些思路,至于具体库的使用上,网上已经有太多基础教程,而坑就靠和去填补吧 。
而为什么大家都懒得写测试——根据本人实际的测试体验,更多的不是测试,而在于 mock,漫长而痛苦 。
展望未来,自然是希望 AI 能够解决我们大部分烦恼的,比如上文说的「根据提供的能力出集成测试」——这是不是有种输入给 AI 就能给我吐代码,我删删改改就能跑的美好错觉呢 。
最后: 下方这份完整的软件测试视频学习教程已经整理上传完成,朋友们如果需要可以自行免费领取 【保证100%免费】
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!