前端单元测试

我是图片

测试是个永恒的主题,我们一起探寻一下前端单元测试的来龙去脉。

  1. 定义
  2. 为什么要写单元测试
  3. 什么项目写单元测试
  4. 测试要写多细
  5. 什么时候写
  6. 如何写单元测试

定义

单元测试在维基百科上的定义为

单元测试(英语:Unit Testing)又称为模块测试,是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。

在前端中,模块可以指功能模块和组件模块,也就是一个函数,一个类或者是一个组件。

为什么要写单元测试

项目的发展越来越大,模块与模块之间的联系和逻辑越来越复杂,错误信息定位也越来越难排查,在这样的项目下开发新功能和重构,付出的时间成本,管理成本大。

这就是单元测试存在的意义:

  1. 减少发开新特性产生的bug
  2. 促进重构
  3. 作为项目文档的补充以便理解和熟悉代码
  4. 减少手动测试的成本

什么项目写单元测试

不是任何项目都要写单元测试,毕竟写测试用例会增加开发的工作量。写单元测试的项目需要满足一下几个条件(但不限于):

  1. 项目的愿景清晰。规模大,模块多,交互多。
  2. 项目服务的用户量多
  3. 开发新功能引发其他模块bug的情况层出不穷
  4. 测试妹子测不过了

测试要写多细

极限编程、测试驱动开发和单元测试以及JUnit的创造者Kent Beck在StackOverflow上,对于单元测试应该写到什么程度的问题作出的回答是:

老板为我的代码付报酬,而不是测试,所以,我对此的价值观是——测试越少越好,少到你对你的代码质量达到了某种自信(我觉得这种的自信标准应该要高于业内的标准,
当然,这种自信也可能是种自大)。如果我的编码生涯中不会犯这种典型的错误(如:在构造函数中设了个错误的值),那我就不会测试它。我倾向于去对那些有意义的错误
做测试,所以,我对一些比较复杂的条件逻辑会异常地小心。当在一个团队中,我会非常小心的测试那些会让团队容易出错的代码。

鉴于前辈的观点,得出测试用例并不是写越全就越好,而应该将测试用例重点覆盖在关键代码上,尽量让测试有意义。这样的代码类型有:

  1. 逻辑复杂,容易出错的代码
  2. 核心的业务代码
  3. 公共的代码
  4. 不易理解,回头会忘的代码

什么时候写

类型 介绍 好处 坏处
开发前写好测试用例 属于TTD模式,测试驱动开发 TTD是被证明能有效提高代码质量的测试手段 不适用需求多变的前端模块,测试用例也要跟着变
开发中写测试用例 先写好一部分功能代码,紧跟着写测试用例 测试随着业务代码同步 相对于开发前要好一点
开发后写测试用例 当完成功能后再补上测试用例 这时有些业务和模块已经稳定下来 假如单元的逻辑比较复杂,测试的点会多,为了较快的写好用例,用例的粒度会变“粗”

对比过后,一般比较推荐在开发需求中,功能代码与测试用例同步进行。

如何写单元测试

首先要注意,单元测试难的不在于如何写,而在于代码设计,模块与模块之间要相互独立,将代码划分为单元可测的代码,单元可测的代码不应该依赖其他模块,不涉及IO操作,这里的IO操作不仅是指读写文件,操作数据库,还包括AJAX请求,本地存储,DOM操作等与浏览器API相关的操作。合理划分模块,模块间解耦,尽量不要相互引用,这也是书写代码的良好习惯,所以好的单元测试有利于促进系统模块的合理划分。

至于使用什么测试框架和如何使用的问题,网上有很多资料都有介绍。

对比了前端一些热门的库的测试用例,既有UI库也有功能库,它们的测试用例的类型如下表所示。

项目 测试框架 单元 测试用例
Element Karma 组件 构建是否成功、属性的UI表现是否一致、触发的事件运行是否预期
Ant-design-vue jest 组件 属性的UI表现是否一致、交互事件触发是否预期、边界情况是否被处理
Axios Mocha、Karma 类和函数模块 模块的功能点是否正常
Vue应用项目 Vue Test Utils(官方推荐) 组件、Util函数模块、Store模块、API模块 渲染dom后检验页面显示的数据、检验调用API(不访问网络,需要mock数据)、Vuex的store、commit或dispatch的检查和检测用户交互等

UI库以组件为单元,功能库以类或函数模块为单元。而在业务项目中,划分的模块往往包括组件、Util函数模块、Store模块、API模块等等。单元测试不可能把这么多模块的功能点都一一覆盖,像上面所说的我们需要挑拣出重要的、复杂的和易出错进行单元用例覆盖,至于那些多变的不重要的功能点可以先不用针对写测试用例。

小结

以上内容包括了对单元测试概念性和适用性的讲解,只希望能起到前端单元测试指引性的作用,大概意识到才能样的项目需要引入单元测试,单元测试用例需要覆盖的点,以及知道如何上手应用框架,至于具体怎样引入到项目里面,网上教程比我写的都要好,而且我也还没在真正在项目中引入(哈哈,纸上谈兵扯理论)。。。

参考文档: