背景:随着项目的不断扩大,代码的修改边界往往难以进行判断准确,而且当有新的同事进行处理原有代码时,其往往需要花费很长时间来确定代码的原有逻辑,防止改动后使原有的完整功能出现问题。其次就是在我们编写组件时常常会因不断的添加方法等,把一个类变得十分的巨大,但是当在前期进行单元测试的编写后再开始进行具体编写,这样往往会使代码结构变得更加的简洁与清晰。
使用流程
1. 首先进行jest的安装 当前jest版本使用了22.4.3。 前期安装时使用了24.0版本。但是由于在本项目中babel-core使用的版本为6.13.2。而24版本不支持6版本,官方文档如下。
但当安装了24版本后,则需要进行关于babel的十分繁杂的兼容版本处理,且当babel升级后会产生很多的版本冲突问题,因此建议babel如果当前为6.*版本,那么jest则使用22版本。
2. 当我们想要测试react中的组件时,我们便要使用enzyme库进行测试。jest提供断言,异步测试,函数的mock等,而enzyme则主要进行react组件的深浅层渲染及元素的查找,因此基础的单元测试将这两个库结合起来使用即可。
我们总结下来需要以下几个库
-
"jest": "^22.4.3",
-
"babel-jest": "^22.4.3" // 使jest支持es6
-
"enzyme": "^3.10.0"
-
"enzyme-adapter-react-16": "^1.14.0" // 由于项目中使用
react为16版本,故需要安此进行版本兼容 -
"identity-obj-proxy": "^3.0.0" // 用来处理对于图片,音乐等的mock
npm install babel-jest jest@22.4.3 enzyme enzyme-adapter-react-16 identity-obj-proxy -D
3. 这时候可能有读者会疑问 jest如何判断哪些是单元测试的文件。当不进行对jest进行配置时,那么jest会默认匹配default: [ "**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)" ]文件。如果你想进行配置,那么你可以在pack.json中进行testMatch配置
4.一切准备好之后我们进行运行jest中最简单的例子,这时我们会发现,报错了!
localStorage is not available for opaque origins
通过网上查询说在jest配置中添加verbose和testURL属性即可 但通过笔者试验,只添加testURL属性即可 ,verbose属性主要配置是否打印出细节。
那么jest总体的配置如下
"scripts":{
...
"test":"jest"
}
"jest": {
"verbose": true,
"testURL": "http://localhost/",
"transform": {
"^.+\\.(jsx|js)?$": "babel-jest"
},
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|css|less|scss)$": "identity-obj-proxy"
},
"globals": {
"xu": {
"device":{}
}
}
/* "testMatch":["<rootDir>/**/*.js"] */ 仅供示范
}
ps:上述globals为全局变量配置,因为在代码中会出现window.xu.device等全局变量的编写,因此需要将其置于globals属性中。
以上jest的安装及基础配置便写到这里 具体配置详见官方文档jestjs.io/docs/en/con…
——————————————————————————————————————————
接下来便进行测试实例的编写,我们先讲解官网上最简单的例子
function sum(a, b) {
return a + b;
}
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
}); // 运行npm test 即可
上面的官方例子便是最简单的一个小的单元测试例子,其含义理解为断言向sum函数输入1,2两个参数,那么其输出结果为3。简单的函数输入输出我们大概了解 ,接下来我们将进行组件的测试。在写组件测试前,我首先查找了对于单元测试公认的一些规范(其实就是FaceBook的规范)
1. 测试文件统一在src/__tests__目录中维护
2. 测试文件命名与React组件命名保持一致,后面以.spec.js结尾
3. 测试用例使用test("功能描述",()=>{})函数描述用例单元
4. 一组功能集合测试使用describe("功能集合描述",()=>{})函数描述功能集合
5. UI测试套件统一使用enzyme
6. React组件测试用例必须包含
- API属性覆盖性测试用例
- DOM快照比对,幂等校验
- 私有Utils函数测试用例
7. 对DOM结构做用例校验
8. bugfix/feature addtion必须要有对应的单元测试用例才能发布
9. 团队协作,MR/PR必须要有对应的单元测试用例才能发布
以上便是facebook对于单元测试及发布时所需的要求 但是对于需求十分紧急或者大量业务代码突增时我们不可能全部实现,因此应该具体情况具体应用。正如腾讯部人员所说
但是却仍不能否定单元测试对于项目稳定性起到的巨大作用。