人在吃秤在看,三高一直往上窜,人要多锻炼多学习,所以恰饭后或者喜欢摸鱼梭哈的小伙伴,不如静下心来学习“3分钟”,毕竟学习也是一种投资,不多BB。
Jest官网入口:www.jestjs.cn
如有更细节的可以参考以下资料:
前端自动化测试 jest 教程 1-配置安装
前端自动化测试 jest 教程 2-匹配器 matchers
前端自动化测试 jest 教程 3-命令行工具
前端自动化测试 jest 教程 4-异步代码测试
前端自动化测试 jest 教程 5-钩子函数
前端自动化测试 jest 教程 6-mock 函数
前端自动化测试 jest 教程 7-定时器测试
前端自动化测试 jest 教程 8-snapshot 快照测试
做测试的目的
1、为了证明我们在写某段代码模块和我们期望的一致,提高软件质量,降低开发成本(注:需要要花费一定时间的,当业务需求不紧急的时候,完善单测可以保障代码质量)
2、多人协作时相互之间未知逻辑的改动等产生的未知或新问题的预警,有效避免一些未考虑到及低级的错误,能更准确更全面地查找错误,提高软件质量。
3、编写测试代码的过程,往往可以让我们深入思考业务流程,让我们的代码写的更完善和规范。
关于Jest 测试框架概述
Jest 是FB团队推出的一个测试框架, 其一大特点是内置了常用的测试工具。
比如:自带断言(expect),测试覆盖率工具(coverage),实现了开箱即用等。
Jest 可以利用其特有的快照测试功能, 通过比对UI代码生成的快照文件, 实现对React等常见框架的自动化测试。
此外,Jest 测试用例是并行执行的, 而且只执行发生改变的文件所对应的测试,提升了测试速度。
Jest 支持 Babel、TypeScript、Node、React、Angular、Vue等
自动化测试主要工作
需要我们手动编写测试代码,当部分逻辑发生改变时,也需要同步更新我们的测试代码。从一定的角度上它也间接的提高了开发及维护成本。这点在实际开发运用中,大家根据实际项目情况来衡量。
测试类型
单元测试:指一个可独立运行的代码段,对最小单元进行功能、性能、接口和设计约束等正确性检验,主要- 测试其在语法、格式和逻辑上的错误。
功能测试:相当于是黑盒测试,测试者不了解程序的内部情况,不需要具备编程语言的专门知识,只知道程序的输入、输出和功能,从用户的角度针对软件界面、功能和外部结构进行测试,不考虑内部的逻辑。
集成测试:在单元测试的基础上,将所有模块按照设计要求组装成子系统或者系统,前端,集成测试可以理解为对多个模块实现的一个交互完整的交互流程进行测试。
冒烟测试:在正式全面的测试之前,对主要功能进行测试,确认主要功能是否满足需要,软件是否能正常运行。
单元测试和静态测试(有人问,所以顺便普及一下)
白盒测试
- 语句覆盖测试
- 判定覆盖测试
- 条件覆盖测试
- 判定—条件覆盖测试
- 条件组合测试
- 路径覆盖测试
黑盒测试
- 等价类划分方法
- 边界值分析方法
- 错误推测方法
静态测试
- 代码走查
- 代码审查
- 代码评审
框架类型
测试框架可分为两种: TDD(测试驱动开发)和 BDD(行为驱动开发)。
TDD:测试驱动开发,强调的是一种开发方式,以测试来驱动整个项目,简单的来说就是先编写测试代码,然后使得所有测试代码都通过为目的,编写逻辑代码,是一种以测试来驱动开发过程的开发模式。
BDD:行为驱动开发,简单的来说就是先编写业务逻辑代码,然后以使得所有业务逻辑按照预期结果执行为目的,编写测试代码,是一种以用户行为来驱动开发过程的开发模式。\
常见的测试框架
Jasmine:多种风格的测试框架,在业内较为流行,功能很全面,自带 asssert、mock 功能
Mocha:可以在 node 和 browser 端使用,具有很强的灵活性,可以选择自己喜欢的断言库,选择测试结果的 report
Qunit:该框架诞生之初是为了 jquery 的单元测试,后来独立出来不再依赖于 jquery 本身
接下来我们主要介绍 Jest ,同时也是react官方推荐的:
Jest特点
易用性:基于Jasmine,提供断言库,支持多种测试风格
适应性:Jest是模块化、可扩展和可配置的
沙箱和快照:Jest内置了JSDOM,能够模拟浏览器环境,并且并行执行
快照测试:Jest能够对React组件树进行序列化,生成对应的字符串快照,通过比较字符串提供高性能的UI检测
Mock系统:Jest实现了一个强大的Mock系统,支持自动和手动mock
支持异步代码测试:支持Promise和async/await
自动生成静态分析结果:内置Istanbul,测试代码覆盖率,并生成对应的报告
JEST 语法
匹配器
expect:返回一个'期望‘的对象
toBe:使用 object.is 去判断相等
toEqual:递归检测对象或数组的每个字段
not:测试相反的匹配 \
真值
toBeNull:只匹配 null
toBeUndefined:只匹配 undefined
toBeDefined:与 toBeUndefined 相反
toBeTruthy:匹配任何 if 语句为真
toBeFalsy:匹配任务 if 语句为假 \
数字
toBeGreaterThan:大于
toBeGreaterThanOrEqual:大于等于
toBeLessThan:小于
toBeLessThanOrEqual:小于等于
toBeCloseTo:比较浮点数相等 \
字符串
toMatch:匹配字符串
Array
toContain:检测一个数组或可迭代对象是否包含某个特定项
异常
toThrow:测试某函数在调用时是否抛出了错误
Enzyme
Enzyme是开源的一个React的JavaScript测试工具,使React组件的输出更加容易进行推断。
Enzyme的API和jQuery操作DOM一样灵活易用,因为它使用的是cheerio库来解析虚拟DOM,而cheerio的目标则是做服务器端的jQuery。Enzyme兼容大多数断言库和测试框架,如chai、mocha、jasmine等
enzyme支持三种方式的渲染
shallow:浅渲染,是对官方的Shallow Renderer的封装。将组件渲染成虚拟DOM对象,只会渲染第一层,子组件将不会被渲染出来,因而效率非常高。不需要DOM环境, 并可以使用jQuery的方式访问组件的信息
render:静态渲染,它将React组件渲染成静态的HTML字符串,然后使用Cheerio这个库解析这段字符串,并返回一个Cheerio的实例对象,可以用来分析组件的html结构
mount:完全渲染,它将组件渲染加载成一个真实的DOM节点,用来测试DOM API的交互和组件的生命周期,用到了jsdom来模拟浏览器环境,需要安装 yarn add jsdom
Enzyme常用函数
- simulate(event, mock):用来模拟事件触发,event为事件名称,mock为一个event object;
- instance():返回测试组件的实例;
- find(selector):根据选择器查找节点,selector可以是CSS中的选择器,也可以是组件的构造函数,以及组件的display name等;
- at(index):返回一个渲染过的对象;
- get(index):返回一个react node,要测试它,需要重新渲染;
- contains(nodeOrNodes):当前对象是否包含参数重点 node,参数类型为react对象或对象数组;
- text():返回当前组件的文本内容;
- html(): 返回当前组件的HTML代码形式;
- props():返回根组件的所有属性;
- prop(key):返回根组件的指定属性;
- state():返回根组件的状态;
- setState(nextState):设置根组件的状态;
- setProps(nextProps):设置根组件的属性;
如何编写测试用例?
通常测试文件名与要测试的文件名相同,后缀为.test.js,所有测试文件默认放在类似于__test__自定义文件夹中
测试文件中应包括一个或多个describe, 每个 describe 中可以有一个或多个it,每个describe中可以有一个或多个expect.
describe(测试套件)块之中,提供测试用例的四个函数:before()、after()、beforeEach()和 afterEach()。它们会在指定时间执行(如果不需要可以不写)
代码模板:
安装
yarn add --dev jest
jest --init (会自动生成coverage文件,名称可以在jest.config.js里配置)
yarn add --dev enzyme
yarn add --dev babel-jest @babel/core @babel/preset-env
在项目的根目录下创建 babel.config.js ,通过配置 Babel 使其能够兼容当前的 Node 版本。
使用ts的,通过 Babel,Jest 能够支持 Typescript
yarn add --dev @babel/preset-typescript
然后将 @babel 添加到 babel.config.js 中的 presets 列表中。\
覆盖率概述
Jest 还提供了生成测试覆盖率报告的命令,只需要添加上 --coverage 这个参数即可生成,再加上--colors 可根据覆盖率生成不同颜色的报告(<50%红色,50%~80%黄色, ≥80%绿色)
- Stmts 是语句覆盖率(statement coverage):是否每个语句都执行了
- Branch 分支覆盖率(branch coverage):是否每个分支代码块都执行了(if, ||, ? : )
- Funcs 函数覆盖率(function coverage):是否每个函数都调用了
- Lines 行覆盖率(line coverage):是否每一行都执行了
测试覆盖率,简单来说就是我们业务代码中,编写测试代码的比例,jest给我们提供了直接生成测试覆盖率文件的方法,也就是运行jest命令时后面加上--coverage参数,我们修改package.json文件如下:
当前我们项目使用的是umi,所以直接在后面加 --watch 就ok了
安装完成后,运行 yarn test
注:类似以下截图:
这尼玛都是啥!啥!啥!由于这是测试刚刚开始,所以覆盖率看起来比较丑,我骄傲了么!
同时,我们发现,文件夹下自动生成了一个coverage文件夹:
我们在浏览器中运行
index.html,如下图:
这个页面向我们展示了项目中不同文件的测试覆盖率,我们可以点击不同文件名字进入查看具体一个文件中,哪些代码被测试到了,哪些没有被测试到
Jest 的冷启动时间有点长怎么办
--watch / --watchAll 启动 jest 的 watch mode,二次启动的速度会比较快
这里对watch模式的几个有用功能做一个简单介绍(也就是图中英文说明):
- 按
a键运行所有测试代码 - 按
f键只运行所有失败的测试代码 - 按
p键按照文件名筛选测试代码(支持正则) - 按
t键按照测试名筛选测试代码(支持正则) - 按
q键盘推出watch模式 - 按
enter键触发一次测试运行
握着你的手教你Jest用法(文字直接看注释就行了)
车辆管理组件--图片展示
车辆管理组件--代码展示
测试样式是否正常
运行测试:
我们发现运行正常,否则失败会显示以下信息:
很明显我把组件故意加了Vehicles12,则提示错误。
组件包含一个input框
运行测试:
组件input框组件车辆编号,初始化应该为空
运行测试:
组件input框内容,当用户输入时会跟随变化
运行测试:
当列表数据为空时 列表无内容
运行测试:
当列表数据不为空时count数目现实数据长度 列表不为空
运行测试:
异步代码测试车辆列表接口是否存在及正常
运行测试:
Mock 测试使用 jest.fn() 模拟函数
运行测试:
测试 jest.fn() 函数的返回值
运行测试:
测试 jest.fn() 函数的传参数是否符合预期
运行测试:
总结
拖了👌🏻,基本官网也比较的清晰。\
这篇文章个人认为已经把jest的基础和最核心的内容做了阐述,可能我们开发过程中,使用react(jest+ enzyme)这样的开发框架,使用webpack这样的工程化工具,在使用jest的时候,会结合使用一些开源库,我相信学好了jest本身之后,配置和使用它们都不会有太多困难。
最后,希望这篇文章可以帮助到大家,感谢能看到这里的每一个小伙伴。