测试自动化的好处在于反馈及时,能够极大地提高前端的开发效率。
在我们日常的开发过程中,是不是经常需要在项目跑起来之后去人工测试某些操作或者流程是否能够正常运行?是不是经常需要打断点或者使用 console.log
查看控制台信息来检查某个函数是否执行?
这些需要我们自己手工测试代码的执行结果是否符合预期的场景,完全可以使用自动化测试的脚本代替。
现有的很多成熟的自动化测试框架完全可以模拟我们的手工操作,使用脚本自动运行测试用例,通常只需要几秒就能给出准确的反馈,同时还能侦听代码变化,自动执行项目中发生了变化的代码对应的测试用例,能够极大提高我们的开发效率。
在公司业务和人员变动都比较快的当下,编写自动化测试脚本的收益越来越高。开发者再也不用害怕引入回归 BUG,也再也不用害怕把代码交给他人维护。有了测试脚本的约束,迭代/重构都能更加从容。
有哪些测试类型?
前端测试主要分为 3 种:单元测试(Unit Test)、集成测试(Integration Test)、UI 测试(UI Test)
单元测试(Unit Test)
单元测试是最容易实现的:代码中多个组件共用的工具类库、多个组件共用的子组件等。
通常情况下,在公共函数/组件中一定要有单元测试来保证代码能够正常工作。单元测试也应该是项目中数量最多、覆盖率最高的。
能进行单元测试的函数/组件,一定是低耦合的,这也从一定程度上保证了我们的代码质量。
集成测试(Integration Test)
集成测试通常被应用在:耦合度较高的函数/组件、经过二次封装的函数/组件、多个函数/组件组合而成的函数/组件等。
集成测试的目的在于,测试经过单元测试后的各个模块组合在一起是否能正常工作。会对组合之后的代码整体暴露在外接口进行测试,查看组合后的代码工作是否符合预期。
集成测试是安全感较高的测试,能很大程度提升开发者的信心,集成测试用例设计合理且测试都通过能够很大程度保证产品符合预期。
UI 测试(UI Test)
在我学习查阅文献的过程中,我发现国内不少文章都将 UI 测试(UI Test)和端到端测试(E2E Test)混为一谈,认为是同一个测试类型。
事实上,UI 测试(UI Test)和端到端测试(E2E Test)是稍有区别的:
UI 测试(UI Test)只是对于前端的测试,是脱离真实后端环境的,仅仅只是将前端放在真实环境中运行,而后端和数据都应该使用 Mock 的。
端到端测试(E2E Test)则是将整个应用放到真实的环境中运行,包括数据在内也是需要使用真实的。
就前端而言,UI 测试(UI Test)更贴近于我们的开发流程。在前后端分离的开发模式中,前端开发通常会使用到 Mock 的服务器和数据。因而我们需要在开发基本完成后进行相应的 UI 测试(UI Test)。
UI 测试的自动化程度还不高,大多数还依赖于手工测试。
在一些自动化测试工具中有创建快照的功能,也能帮助我们在一定程度上实现 UI 测试(UI Test)的自动化。
哪些项目适合引入自动化测试?
适合引入自动化测试的场景:
- 公共库类的开发维护
- 中长期项目的迭代/重构
- 引用了不可控的第三方依赖
这些场景是需要引入自动化测试来对现有代码进行约束的。尤其是中长期项目,迭代/重构时人力回归困难,自动化测试就显得尤为重要!
如何选择测试工具?
现在市面上有很多流行的测试工具,但普遍都存在一个问题:新特性的支持滞后。
前端测试的框架可谓是百花齐放。
- 单元测试(Unit Test)有 Jest,Mocha, Ava, Karma,, Jasmine 等。
- 集成测试(Integration Test)和 UI 测试(UI Test)有 ReactTestUtils, Test Render, Enzyme, React-Testing-Library, Vue-Test-Utils 等。
Jest
- Jest 基于 Jasmine, 做了大量修改并添加了很多特性,同样开箱即用,但异步测试支持良好。
-
Facebook 的一套开源的 JavaScript 测试框架, 它自动集成了断言、JSDom、覆盖率报告等开发者所需要的所有测试工具,是一款几乎零配置的测试框架。并且它对同样是 Facebook 的开源前端框架 React 的测试十分友好
安装
yarn add --dev jest
配置Jest
1.暴露 Jest 配置文件
yarn jest --init
- 选择运行环境
选择jsdom(browser-like)
浏览器环境运行 - 是否生成测试覆盖率报告
按y
- 是否自动清除模拟调用
按y
- 根目录下 jest.config.js 文件既为 jest 配置文件
2.在根目录打开 package.json,添加命令行快捷方式
script:{
"test":"jest --watchAll",
"coverage":"jest --coverage"
}
4.配置babel
- 在根目录创建名为 .babelrc 的文件
"presets":[
["@babel/preset-env", {"targets":{"node":"current"}}]
]
}
当运行 yarn test
时,jest 内部插件 babel-jest 会自动地检测当前环境下是否安装 babel或babel-core,如果安装 babel-core 会根据 .babelrc 的配置,先把代码转化成 jest 能识别的语句,再运行测试
编写你的第一个Jest测试
创建src
和test
目录及相关文件
- 在项目根目录下创建
src
目录,并在src
目录下添加functions.js
文件 - 在项目根目录下创建
test
目录,并在test
目录下创建functions.test.js
文件
Jest会自动找到项目中所有使用.spec.js
或.test.js
文件命名的测试文件并执行,通常我们在编写测试文件时遵循的命名规范:测试文件的文件名 = 被测试模块名 + .test.js
,例如被测试模块为functions.js
,那么对应的测试文件命名为functions.test.js
。
在src/functions.js
中创建被测试的模块
export default {
sum(a, b) {
return a + b;
}
}
在test/functions.test.js
文件中创建测试用例
import functions from '../src/functions';
test('sum(2 + 2) 等于 4', () => {
expect(functions.sum(2, 2)).toBe(4);
})
运行npm run test
, Jest会在shell
中打印出以下消息:
PASS test/functions.test.js
√ sum(2 + 2) 等于 4 (7ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 4.8s