1.什么是测试
测试是一种验证我们的代码是否可以按预期工作的方法。
换句话说就是写一些代码来验证一段代码是否能得到预期设计代码时所期望的结果。
被测试对象可以是样式,功能,流程,组件等。
2.前端测试的意义(这里主要指单元测试)
1.检测出一些潜在的bug。
2.快速反馈功能输出,验证代码是否达到预期。
3.保证代码重构的安全性(可参考测试用例达到的效果来进行对应的重构)。
4.方便协作开发(如其他人使用时,可直接阅读测试用例)。
3.几种测试类型
单元测试:
被测试对象为程序中最小组成单元的测试,这里的最小组成单元可以是一个函数function,一个方法集合module,或者类等等。可以做到孤立的验证。
其中要注意,需要访问数据库,访问文件系统,测试网络等的不算是单元测试。
集成测试:
测试一些I/O依赖。比如一些依赖ajax或者localStorage等的代码。例如测试一些接口数据等。
测试一些业务层面上的component。例如测试一个登陆框component的交互等
样式测试:测试央视是否符合设计稿初期。
注:在单元测试中如组成单元拆分够细,可极大减少集成测试与样式测试。
3.单元测试的两个测试方法论:BDD与TDD
TDD测试驱动开发:
基本思路就是通过测试来推动整个开发的进行。
通过测试用例来告诉开发人员要编写什么代码(即测试先于代码)。
BDD行为驱动开发:
与tdd 相反,开发推动测试(即代码先于测试)。
TDD,BDD参考:https://www.cnblogs.com/Leo_wl/p/4780678.html
4.单元测试包涵元素与测试流程
单元测试一般包含以下几个元素:
-
被测试的对象是什么
-
要测试该对象的什么功能
-
实际得到的结果
-
期望的结果
具体到某个单元测试,往往包含以下几个步骤:
-
准备阶段:构造参数等,构造所需测试的条件
-
执行阶段:用构造好的参数执行被测试代码
-
断言阶段:用实际得到的结果与期望的结果相比较,以判断测试是否正常
例如:
元素:
被测试的对象是什么: NumberFilter
要测试该对象的什么功能:格式转换
实际得到的结果:result
期望的结果: expectedResult
步骤:
准备阶段:line1 - line5,line7
执行阶段:line6
断言阶段:line8
5.几种测试框架
5.1 react官方文档中自带的两个用于测试组件的库。
React-test-renderer:负责将组件输出成json对象以便我们遍历,断言或是进行snapshot快照测试。
文档可参考:https://reactjs.org/docs/test-renderer.html
例如:
button组件
button的测试文件:
通过调用 renderer 的 create 传入要 render 的组件来获得一个实例,然后调用该实例上存在的方法和属性来测试该组件。
React-dom/test-utils:
包含在react-dom中的辅助测试工具。主要作用是帮我们遍历ReactDOM 生成的DOM 树,方便我们编写断言。注意:使用该库时必须提供一个DOM 环境。当然这个DOM 环境可以是 jsdom 这种模拟环境。(Jest 默认的执行环境就是jsdom)
文档可参考:https://reactjs.org/docs/test-utils.html
用法基本与 React-test-renderer 类似,因此基本只使用 React-test-renderer 就能满足平常的大部分要求。
5.2 airbnb的enzyme
前面已经介绍完了React自带的两个测试工具库。接下来简单介绍一下由Airbnb 开源的React 测试工具库 Enzyme。
Enzyme 底层其实也是基于 react-test-renderer 和 react-dom/test-utils 的。但它在二者的基础上进行了封装提供了更加简单易用的查询、断言方法。
Api的 侧重点更多着重于渲染react组件和从dom树种检索指定的节点。
三种渲染组件的方法:
- shallow():浅渲染,当没有和dom互动,不涉及子组件时,会渲染至虚拟dom,不会返回真实dom节点,(能很好的提高测试性能)
例如:对BaseTitleDescribe组件的一个title内容测试用例
一般可用来测试一些表层数据等
- render():类似shallow(),渲染出最终的html,返回一个实例对象
例如:对BaseTitleDescribe组件的一个span标签数量的测试用例
一般可用来测试接受复杂数据时,组件的渲染是否按需渲染
- mount():将组件真实加载,加载为真实dom
例如:对autocomplate自动补全组件的功能测试
一般用于测试组件的功能等,模拟事件等
具体文档可参考:https://airbnb.io/enzyme/docs/api/index.html
5.3 mocha,chai,
mocha是一款能在浏览器和node环境运行的的单元测试框架
搭配chai做断言能达到jest的效果
5.4 facebook的jest
facebook开发并维护的一套开源测试框架,目前已经发布了jest 23,自身集成了断言等功能,某些层面上相当于mocha + chai,却更简洁高效。
5.4.1简化的api
-
灵活的配置:可写在package.Json 或jest.config中,自由配置
-
匹配表达式,内置断言:可以使用期望(expect)来验证不同内容
-
测试异步:支持promise,async/await
-
模拟函数:可以修改或者检查某个函数的行为
5.4.2 watch监控模式
可识别出当前文件相关的其他测试文件并运行,缩短测试时间。
例如:
修改了a.js文件,同时b.js中依赖了a.js,那么此时不仅会运行a。spec.js还会运行b.spec.js。
5.4.3 代码覆盖率
jest内置了代码覆盖率报告功能,可在整个项目里收集代码覆盖率信息,包括未经测试的文件。
- % Stmts是语句覆盖率(statement coverage):是否每个语句都执行了?
- % Branch分支覆盖率(branch coverage):是否每个if代码块都执行了?
- % Funcs函数覆盖率(function coverage):是否每个函数都调用了?
- % Lines行覆盖率(line coverage):是否每一行都执行了?
5.4.4快照功能
快照能够记住当时的测试对象(可为对象,或react element等)的结构并输出成一个单独的.snap 文件用于保存结构。
其中对象会产生一个类json的结构,react element会产生一个类dom结构。
例如下图是对一个raido组件的测试快照用例:
下图是根据用例生成的快照文件:
提交代码时需要将快照文件一同提交,那么在后续执行测试时,会一直比对现有的快照文件。
当改变组件代码时,如果某些改变导致了快照测试失败,那么说明本次修改存在问题,可修复直到测试通过。如果是有意更改,可以通过 更新 来实现更新快照。