写在开头: html
单元测试对于不少人比较模式,它是一种推进开发,或者提升产品质量的手段, 前端
我画一张图,你们就能理解react
其实单元测试,就是先编写单元测试代码,而后使用单元测试框架,去模拟环境(例如浏览器),而后运行你的代码,看代码是否按预期运行web
这里为了下降文章篇幅,对于初学者更友好,因而这里使用我开源的通用脚手架,集成TypeScript+JavaScript混合开发,Jest框架,测试React组件、Enzyme、dva、Antd按需加载等主流技术~ 推荐你们使用npm
我开源的脚手架在npm上叫:ykj-cli json
使用步骤:后端
npm i ykj-cli -g 或 yarn add global ykj-cli ykj init project_name cd project_name yarn && yarn dev 便可打开看到页面~
有什么问题或者建议能够提给我,我会即时改进,欢迎大家在项目中使用。我已经集成了PWA等功能,后期会按需加入更多可选功能浏览器
开始编写第一个单元测试代码antd
全部的测试代码必须在test文件夹下,咱们的脚手架已经帮咱们作好了 app
新建一个app.test.tsx文件(必须是tsx结尾,由于要测试React组件)
一个合格的React项目,组件必须是tsx结尾,工具文件以ts结尾,声明文件以.d.ts结尾
首先引入enzyme和React以及对应的组件
import App from '../src/app'; import { mount } from 'enzyme'; import React from 'react';
编写单元测试代码:
test('login test', async () => { console.log('App-mountComponent test function begin '); });
每一个test是一个单独的测试函数,咱们使用封装好脚手架封装好的命令,测试一把看看
yarn test
发现没有反应,这是为何?由于里面没有写任何单元测试代码,此时咱们根据脚手架的实际文件来编写单元测试代码
import App from '../src/routers/home'; import { mount } from 'enzyme'; import React from 'react'; import toJson from 'enzyme-to-json'; //作快照 test('login test', async () => { console.log('App-mountComponent test function begin '); const wrapper = mount(<App />); expect(wrapper.find('.login_fade_in').children().length).toBe(8); console.log('App-mountComponent test function stop --success '); });
此时 yarn test 启动测试
发现报错,由于App组件是链接了dva的store数据中心,这里没有传入props
那么咱们能够模拟传入store吗? 最简单的方法,试试传入一个空对象
import App from '../src/routers/home'; import { mount } from 'enzyme'; import React from 'react'; import toJson from 'enzyme-to-json'; //作快照 test('login test', async () => { console.log('App-mountComponent test function begin '); const wrapper = mount(<App store={{}}/>); expect(wrapper.find('.login_fade_in').children().length).toBe(8); console.log('App-mountComponent test function stop --success '); });
yarn test
启动结果
发现报错,测试没有经过,那么咱们要想办法让它测试经过,因而就要看看App.tsx组件须要什么props~
import React, { Fragment } from 'react'; import { Button } from 'antd'; import { connect } from 'dva'; import './index.less'; interface Props { history: any; readonly count: number; dispatch: Function; list: Array<string>; }
这里又要提到TypeScript是真香,个人脚手架支持TS和JS混合开发,赶忙来把~
一看原来须要传入四个必须的参数,那么咱们模拟一份吧,此次是认真的测试哦~
import App from '../src/routers/login'; import { mount } from 'enzyme'; import React from 'react'; import toJson from 'enzyme-to-json'; //作快照 test('login test', async () => { console.log('App-mountComponent test function begin '); const wrapper = mount(<App Name="Peter Hello" changeShowContent={() => {}} />); expect(wrapper.find('.container').length).toBe(1); console.log('App-mountComponent test function stop --success '); });
上面单元测试代码意思是:
这里⚠️:若是是断言,须要判断值的,使用toBe,若是是
对象要进行比较的,使用toEqual
yarn test
测试结果经过,这就是一个最简单的单元测试编写,一般推荐根据需求先编写单元测试代码,再进行业务代码编写
而后生成单元测试报告
yarn test-c
此时能够看到根目录的coverage文件夹下有了lcov-report文件夹,进入后咱们直接打开里面的index.html文件,能够看到单元测试报告
这样里面有一些像分支覆盖率、函数、代码函数覆盖等
其实像Jest用起来仍是比较方便的,核心理念就是使用测试框架运行业务代码,再用单元测试代码去检测你的业务代码,先后端单元测试理念其实都是同样的思想,检测代码运行结果嘛。其余的API这里就不作解释了,有兴趣的能够用ykj-cli这个脚手架试验一把,上面的例子都在里面,很是方便
前端单元测试还有一个很重要的一点,就是生成页面快照
为何要生成页面快照?
你能够先在某个时间端生成页面快照,保存。
而后等部分代码跑完后,再生成一次快照,跟以前的快照进行对比,这样就能判断你中间的这部分代码有没有影响UI,这样能肯定有没有BUG的出现
页面快照:
import App from '../src/routers/login'; import { mount, shallow } from 'enzyme'; import React from 'react'; import toJson from 'enzyme-to-json'; //作快照 test('login test', async () => { console.log('App-mountComponent test function begin '); const wrapper = shallow(<App Name="Peter Hello" changeShowContent={() => {}} />); // toJson(wrapper, { // noKey: false, // mode: 'deep', // }); expect(wrapper).toMatchSnapshot() console.log('App-mountComponent test function stop --success '); });
这里 expect(wrapper).toMatchSnapshot() 这行代码,帮咱们在test文件夹下生成了__snapshots__文件夹
后面测试代码中若是有操做改变了这个页面,那么就会报错,单元测试不经过
下面的内容但愿你也能认真看完
常见的单元测试代码例子
单元测试的编写难度可能比业务代码难度更高,本文带你入门,没有问题,其余的API须要你去多看文档,学习,多写。
推荐一些资料:
http://caibaojian.com/scb/enzyme.html
原创很累,感受有帮助,点个赞,关注下 前端巅峰
公众号。推荐一下文章给须要的人吧