前端测试的作用与价值

一句话总结测试的重要性:如果你需要快速的去修改某段陈年代码又不清楚改完后有没有其它副作用,一个详细的测试代码就能帮助你,给予你信心和安全感去改动这段代码。

测试的价值:尽可能减少修改代码所带来的未知问题,在项目上线前就扼杀掉。

测试的种类有几种?

  1. unit test
    特指: 公共函数/组件 这一类低耦合的代码。

通常情况下,在公共函数/组件中一定要有单元测试来保证代码能够正常工作。单元测试也应该是项目中数量最多、覆盖率最高的。

评价:我认为单元测试应该是项目的主流,因为他的投入成本较低,回报率相对业务代码高,因为 公共函数/组件 使用率高。

  1. intergration test
    特指: 耦合度较高的函数/组件、经过二次封装的函数/组件、多个函数/组件组合而成的函数/组件 的代码。

评价:虽然集成测试是安全感较高的测试,能很大程度提升开发者的信心,集成测试用例设计合理且测试都通过能够很大程度保证产品符合预期。但是成本和回报率相对于单测要低。因为需求的频繁变化会导致测试代码的编写变得无用,所以集成测试也不太适合在国内公司落地。

  1. UI test
    特指: 类似于用 puppeteer 这类无头浏览器获取渲染结果进行对比

评价: 个人觉得这个价值回报过低,或者没有,花了一堆时间去测试两张图片的不同,感觉并不划算。

什么地方适合引入测试?

  1. 公共库类的开发维护 (成本低,回报高)
  2. 中长期项目的迭代/重构 (需求稳定,改动的可能性低)

测试的思想

  1. TDD:Test-Driven Development(测试驱动开发)
    TDD 则要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行

  2. BDD:Behavior-Driven Development(行为驱动开发)
    BDD 可以让项目成员(甚至是不懂编程的)使用自然语言来描述系统功能和业务逻辑,从而根据这些描述步骤进行系统自动化的测试

相关实践案例。(Vue 与 Jest)

Jest 的介绍与使用

Jest 是一款测试框架,其生态丰富,对 Vue 开发者友好。尤其是配合 vue-test-utils 可以做到 Vue 组件级的测试。

基本使用

安装

npm i jest -D

在 package.json 文件中添加脚本

"scripts": {
  "test": "jest"
}

运行:npm run test 。jest 会在全局目录上自动扫描 .(test|spec).(js|ts) 的文件并执行相应的测试用例,得出最后的测试报告。(可以自行通过 jest.config.js 文件进行更加精细的控制)

常用的测试函数:

本人比较容易弄混淆的一些函数

test (他有个别名函数叫:it,更符合语义化) 和 describe 函数

test 是将运行测试用例的方法,而 describe 是一个将多个相关的测试组合在一起的块(相当于是分组)。即:describe 能包含多个 test ,当然不用 describe 包含也可以,这不是强制的,你甚至可以直接把 test 块直接写在最外层。 但是如果你习惯按组编写测试,使用 describe 包裹相关测试用例更加友好。
大白话:describe 可以包含 test 也可以包含多个 describe 块,而 test 不可以再嵌套 test。

断言函数:

expect(期望),这个通常会和一些匹配函数,期望某个表达式能和某个用例的值匹配上。

匹配函数:
用作判断,而判断的方式有许多种,像简单的 等于 或 不等于,含于 或 不含于。

容易弄混的两个函数:toBe 与 toEqual
toBe 类似三元等于,其实是使用 Object.is() 实现对比。用作对比原始类型的对象
toEqual 是 Object 对象对比,通过递归的形式去深度对比,内部也是通过 Object.is() 去对比原始类型的对象。

toBeTruthy 和 toBeFalsy
首先 Truthy(真值) 并不是特指 true ,而 Falsy(假值) 也不是特指 false
真值是包括这几种:true、非 0 数、非空串。(即:转成布尔类型为 true )
假值是包括这几种:false、0、null、”” 、undefined 和 NaN 六种值。(其实它们转成布尔类型就是 false)

异步匹配:
resolves 和 rejects

题外话:Object.is() 于 == 和 === 的对比

  1. 与 == 对比。
    Object.is 不会强制转换两边的值。

  2. 与 === 对比
    对待有符号的零和 NaN 不同,例如,=== 运算符(也包括 == 运算符)将数字 -0 和 +0 视为相等,而将 Number.NaN 与 NaN 视为不相等。

其它的匹配函数:
not: 用于测试相反的结果,也就是不等于
toMatch(regexpOrString):用来检查字符串是否匹配,可以是正则表达式或者字符串
toContain(item):用来判断 item 是否在一个数组中,也可以用于字符串的判断
toBeNull(value):只匹配 null
toBeUndefined(value):只匹配 undefined
toBeGreaterThan(number): 大于
toBeGreaterThanOrEqual(number):大于等于
toBeLessThan(number):小于
toBeLessThanOrEqual(number):小于等于
toBeInstanceOf(class):判断是不是 class 的实例
anything(value):匹配除了 null 和 undefined 以外的所有值
toHaveBeenCalled():用来判断 mock function 是否被调用过
toHaveBeenCalledTimes(number):用来判断 mock function 被调用的次数
assertions(number):验证在一个测试用例中有 number 个断言被调用

注意:关于 jest 中的一些正则表达式是利用 Glob 这个库进行匹配路径与路径名称,具体文档。

Glob 文档:https://github.com/isaacs/node-glob#readme

快照:

TBD

配置文件的说明

文档:https://jestjs.io/zh-Hans/docs/configuration

常用的配置
reporters => 自定义报告
collectCoverage => 是否收集测试时的覆盖率信息
transformIgnorePatterns => 设置无需编译的代码路径。一般为:[‘/node_modules/‘]
moduleNameMapper => 映射路径。通常是将我们的别名如: @/xxx 路径转成绝对路径,让 jest 识别路径。
collectCoverageFrom => 收集哪些文件的覆盖率。
testMatch => 只执行特定路径下的测试文件

覆盖率报告

在 jest 配置项里配置 collectCoverage: true 时,会生成多种文件类型的报告,可以给一些第三方工具读取生成一些报表提供查看。

Vue 项目中使用 Jest

在 Vue 项目中,我们按照之前谈到的,测试要做到哪一步才比较符合经济性?我分为以下几种场景:

  1. 目标特定属性是否符合预期。(成本较低)比如:
  • Vue 实例(组件)的 props computed watch 中的属性是否达到预期
  • 自定义 events 是否触发
  • 组件的渲染结果:样式、Dom 文本、HTML 快照(即:html 文本)
  1. 组件的异步请求。(成本高)比如:
  1. 涉及 element-ui、vuex 、vue-router 等第三方库的依赖。(成本不好计算,比较复杂,要考虑的地方太多)

因为现在主流的项目构建方式是 Vue2 + Vue-cli 以及 Vue3 + Vite (其实是我认为的),所以我只准备了这两种项目的 jest 配置。

Vue2 + Vue-cli(5.0.8 版本)+ Vue Test Utils

需要准备以下依赖包:(其实 Vue-cli 在可视化下可以创建就可以自动安装好以下依赖包)

  1. @vue/test-utils 是官方的偏底层的组件测试库,它是为用户提供对 Vue 特定 API 的访问而编写的。

    文档地址:https://v1.test-utils.vuejs.org

  2. @vue/vue2-jest 预处理器支持基本的单文件组件功能,但是目前还不能处理样式块和自定义块。
  3. babel-jest JS 语法降级。因为有可能需要测试某些很新的 js 特性时需要用到。
  4. @vue/cli-plugin-unit-jest 预先给你配置好 jest 插件的,带有默认的一些配置,比如:自动给你装以上三个依赖包。
    注意:该库带有部分 jest 配置,详情看以下文档。

    该插件详情:https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-plugin-unit-jest#readme

至此,我们就可以正常测试了。

Vue3 + vite (还未实践过,先鸽了)

TBD

如何落地?如何做好成本的平衡?

该测什么类型的代码?做到哪一步?

摘自:https://juejin.cn/post/6844904194600599560



前端测试 Jest

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!