搭建 Jest+ Enzyme 测试环境
1.为什么要使用单元测试工具?
因为代码之间的相互调用关系,又希望测试过程单元相互独立,又能正常运行,这就需要我们对被测函数的依赖函数和环境进行mock,在测试数据输入、测试执行和测试结果检查方面存在很多相似性,测试工具正是为我们在这些方面提供了方便。
所谓单元测试也就是对每个单元进行测试,通俗的将一般针对的是函数,类或单个组件,不涉及系统和集成。单元测试是软件测试的基础测试。
2.React 的标配测试工具 Jest。
Jest主要有以下特点:
1.适应性:Jest是模块化、可扩展和可配置的。
2.沙箱和快速:Jest虚拟化了JavaScript的环境,能模拟浏览器,并且并行执行
3.快照测试:Jest能够对React 树进行快照或别的序列化数值快速编写测试,提供快速更新的用户体验。
4.支持异步代码测试:支持promises和async/await
5.自动生成静态分析结果:不仅显示测试用例执行结果,也显示语句、分支、函数等覆盖率。
JEST对比Mocha来说,因为如下几个优点最后胜出:
1.和React师出同门,FB官方支持
2.已经集成了测试覆盖率检查、mock等功能,不需要安装额外的库
3.文档完备,官方提供了和babel、webpack集成情况下以及异步调用的测试解决方案
4.官方提供snapshot testing解决方案
3.Jest + Enzyme的使用过程
1.安装
$ nam install —save-dev jest
如果需要在测试项目中使用babel,需要安装babel-jest
$ nam install —save-dev babel-jest
然后安装enzyme
$ npm install enzyme —save-dev
如果使用的react版本在13以上,还需要安装react-addons-test-utils
$ nam i —save-dev react-addons-test-utils
2.配置
JEST运行基础功能虽然无需配置,但是官方依然提供了配置选项来实现个性化需求。
package.json文件中配置jest的collectCoverageFrom参数,来指定检查所有需要测试的文件(无论源文件有没有被测试文件使用到)
coverageThreshold 参数来配置测试覆盖率。
jest.config.js 配置jest:
module.exports = {
bail: true, //遇上 test feature, 则Stop running test, 默认值是false
cacheDirectory: './node_modules/.cache', //测试缓存数据的存储位置
testEnvironment: 'jsdom', //default brower-like enviroment, 如果你搭建了一个node service node-like enviroment
coverageThreshold: { //测试覆盖率, 阈值不满足,就返回测试失败
global: {
branches: 90,
functions: 90,
lines: 90,
statements: 90,
},
},
coveragePathIgnorePatterns: [ //该路径下的测试,忽略在测试覆盖率上
'build',
'<rootDir>/src/shared/libs/url/',
],
testRegex: 'test/.*\\.jsx?$', //要测试的文件目录及后缀
testPathIgnorePatterns: [ //忽略该路径的文件测试
'<rootDir>/node_modules/',
'<rootDir>/build/',
'<rootDir>/scripts/',
'<rootDir>/api/',
'<rootDir>/test/setup.js',
'__mocks__',
],
moduleFileExtensions: ['', 'json', 'js', 'jsx', 'less'], //测试模块中用到的文件的后缀名配置
modulePaths: ['<rootDir>/src', '<rootDir>'],
moduleNameMapper: { //与测试无关的资源文件同意mock 掉,这样在import 的时候就不会真的引入这些文件
'^import?': '<rootDir>/build/jestImportMock.js',
'\\.(css|less|gif|jpg|jpeg|png)$': '<rootDir>/build/jestStyleMock.js',
},
setupFiles: ['<rootDir>/test/setup.js'], //给每个测试文件添加额外的配置
transformIgnorePatterns: [ //测试过程不改变满足配置的文件
'<rootDir>/node_modules/(?!(react-aaui|tempest\\.js)/)',
'babel-runtime',
],
}
4.了解React官方测试工具库
react测试可以分为测试DOM结构 和测试Action和Reducer
React官方测试工具库提供两种测试形式:
1.Shallow Rendering 测试虚拟DOM的方法
Shallow Rendering (浅渲染)指的是,将一个组件渲染成虚拟DOM对象,但是只渲染第一层,不渲染所有子组件,所以处理速度非常快。它不需要DOM环境,因为根本没有加载进DOM。
import TestUtils from 'react-addons-test-utils';
function shallowRender(Component) {
const renderer = TestUtils.createRenderer();
renderer.render(<Component/>);
return renderer.getRenderOutput();
}
Shallow Rendering 函数,该函数返回的就是一个浅渲染的虚拟DOM对象。只有一层,不返回子组件。
2.DOM Rendering 测试真实DOM的方法
官方测试工具库的第二种测试方法,是将组件渲染成真实的DOM节点,再进行测试。这时就需要调用renderIntoDocument 方法。
import TestUtils from 'react-addons-test-utils';
import App from '../app/components/App';
const app = TestUtils.renderIntoDocument(<App/>);
renderIntoDocument 方法要求存在一个真实的DOM环境,否则会报错。因此,测试用例之中,DOM环境(即window, document 和 navigator 对象)必须是存在的
Enzyme库对官方测试库进行了封装,它提供三种方法:
import { shallow, mount, render } from ‘enzyme’
shallow 返回组件的浅渲染,对官方shallow rendering 进行封装
const wrapper = shallow(<Counter {...props} />)
expect(wrapper.find('button').exists()).toBeTruthy()
shallow 返回Counter 的浅渲染,然后调用find 方法查找 button 元素
关于find方法,有一个注意点,就是它只支持简单选择器,稍微复杂的一点的CSS选择器都不支持。
render 方法将React组件渲染成静态的HTML字符串,然后分析这段HTML代码的结构,返回一个对象。它跟shallow方法非常像,主要的不同是采用了第三方HTML解析库Cheerio,它返回的是一个Cheerio实例对象。
const wrapper = render(<Counter {...props} />)
expect(wrapper.find('button').exists()).toBeTruthy()
render方法与shallow方法的API基本是一致的。
Enzyme的设计就是,让不同的底层处理引擎,都具有同样的API
mount 方法用于将React组件加载为真实DOM节点。
const wrapper = mount(<Counter arithmetic={arithmetic})
wrapper.find('button').simulate('click')
Enzyme的一部分API,你可以从中了解它的大概用法。
.get(index):返回指定位置的子组件的DOM节点
.at(index):返回指定位置的子组件
.first():返回第一个子组件
.last():返回最后一个子组件
.type():返回当前组件的类型
.text():返回当前组件的文本内容
.html():返回当前组件的HTML代码形式
.props():返回根组件的所有属性
.prop(key):返回根组件的指定属性
.state([key]):返回根组件的状态
.setState(nextState):设置根组件的状态
.setProps(nextProps):设置根组件的属性
toMatchSnapshot方法会去帮你对比这次将要生成的结构与上次的区别
测试 异步action
他的I/O可能依赖store.getState(),自身又会依赖异步中间件,这类使用原生js测试起来比较困难,我们的目的可以设定为:当我们触发一个action后,它经历了一个圈异步最终store.getAction中的action拿到的数据和我们预期一致。因此我们需要用到两个库:redux-mock-store 和 nock。
const mockStore = configureStore([thunk, promiseMiddleware]) //配置mock 的store,让他们有相同的middleware
afterEach(() =>
nock.cleanAll()
) //每执行完一个测试后,清空nock
const store = mockStore({
router: {
location: '/',
},
}) //以我们约定的初始state创建store,控制 I/O 依赖
const data = [
//接口返回的信息
{…
},
]
nock(API_HOST) //拦截请求返回的response
.get(`/api/…`) //拼接路由,需要在test.js中配置测试路径
.reply(200, {code: 0, data})
return store.dispatch(actions.getAll()).then(() => expect(store.getActions()).toMatchSnapShot())
1.用nock来mock拦截http请求结果,并返回我们给定的response
2.用redux-mock-store 来mock store 的生命周期,需要预先把middleware配成和项目一致
3.describe会包含一些生命周期的api,比如全部测试开始做啥,单个测试结束做啥api,这里每执行完一个测试就清空nock
4.用了jest中的toMatchSnapShot api 来判断两个条件是否一致。
本来你要写成 expect(store.getActions()).toEqual({data …}) 你需要把equal 里的东西都描写具体,而toMatchSnapshot
可在当前目录下生成一个snapshot ,专门存放当前结果,写测试时看一眼是预期的就commit。如果改坏了,函数就不匹配snapshot了。
5.测试注意事项
1.拆分单元,关注输入输出,忽略中间过程。dom测试时只用确保正确调用了action函数,传参正确,而不用关注函数调用结果,置于action处理结果,reducer中对state的改变这些都留给action和reducer自己的单元测试区测。不要想着测试整个大功能的流程,不要有闭环的思想,单元测试需要保证的当前单元正常,对于每个单元模块输入输出都正确,理论串联后一起使用闭环时也会正确。
2.多种情况的测试覆盖,如果不能保证测试的全面性,每种情况都覆盖到,那么这个测试就是个不敢依靠的不全面的测试。当然在实际项目中,可能因为时间、资源等问题,无法保证每种情况都测试到,而只测试主要的内容,这时候要做到心里有数,反正我是对于每个测试都写注释的,交代清楚测试覆盖了哪些,还有哪些没有覆盖,需要其他手段保持稳定性。
3.关注该关注的,无关紧要的mock掉。css、图片这种mock掉,http请求mock掉
4.原本不利于测试的代码还是需要修改的,并不能为了原代码稳定不变,在测试时不敢动原代码。譬如函数不纯,没有返回值等。
搭建 Jest+ Enzyme 测试环境的更多相关文章
- 记录使用gogs,drone搭建自动部署测试环境
使用gogs,drone,docker搭建自动部署测试环境 Gogs是一个使用go语言开发的自助git服务,支持所有平台 Docker是使用go开发的开源容器引擎 Drone是一个基于容器技术的持续集 ...
- docker-compose 搭建 Redis Sentinel 测试环境
docker-compose 搭建 Redis Sentinel 测试环境 本文介绍如何使用 docker-compose 快速搭建一个 Redis Sentinel 测试环境.其中 Redis 集群 ...
- 搭建php渗透测试环境
php服务器下载地址 http://vdisk.weibo.com/s/D9I4jIIfNddvh 在C盘下创建一个www文件夹 安装phpstudy 下一步安装 修改配置文件 将端口改成8080 保 ...
- 搭建asp渗透测试环境
win2k3下载地址 http://yun.baidu.com/share/link?shareid=77306757&uk=2852438886 win2003 Enterprise Edi ...
- 手把手教你搭建hadoop+hive测试环境(新手向)
本文由 网易云发布. 作者:唐雕龙 本篇文章仅限内部分享,如需转载,请联系网易获取授权. 面向新手的hadoop+hive学习环境搭建,加对我走过的坑总结,避免大家踩坑. 对于hive相关docke ...
- selenium===使用docker搭建selenium分布式测试环境
准备: #请在此之前先了解,selenium grid :参考:selenium-grid ,下载地址,win-本地部署过程 >>>环境准备: Linux操作系统 >>& ...
- 使用 Vagrant 搭建 Kubernetes 本地测试环境
Vagrant 中文资料 参考资料 Kubernetes 需要一个至少包含三个节点的分布式系统.如果想学习 Kubernetes,或只是在本地搭建测试环境,则可以通过 Vagrant 来简单的实现. ...
- kubernetes实战之consul篇及consul在windows下搭建consul简单测试环境
consul是一款服务发现中间件,1.12版本后增加servicemesh功能.consul是分布式的,可扩展的,高可用的根据官方文档介绍,目前已知最大的consul集群有5000个节点,consul ...
- 快速搭建appium自动测试环境
首先申明本文是基本于Python与Android来快速搭建Appium自动化测试环境: 主要分为以下几个步骤: 前提条件: 1)安装与配置python环境,打开 Python官网,找到"Do ...
随机推荐
- PXE自动装机
PXE自动装机 一.搭建PXE远程安装服务器 PXE自动装机需要桌面模式 假如不是桌面模式安装的PXE需要安装桌面模式软件包 yum groupinstall "Desktop" ...
- 使用Axure做验证码之获取验证码(一)
本次作业,制作验证码,仅完成获取验证码操作,如下: 分析: 左图为矩形,主要展示验证码(本例设置4位验证码),其中验证码为字母和数字组合: 右图为文本输入框,主要设置点击事件,即点击文本文字,矩形框中 ...
- Good Time 冲刺 二
第二天 日期:2018.6.15 一.今日完成任务情况及遇到的问题 王怡镔: 今天学习了小程序框架和组件方面的知识,在微信开发工具中尝试进行小程序开发,学习视图层与逻辑层的框架与联系. 于鑫宇: 学习 ...
- URL tomcat中文乱码
<Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8" conn ...
- mysql中文、英文别名排序问题,order by 关键字详解
order by 关键字详解: SELECT intcode AS 商品编码, product_title AS 名称, retailprice AS 零售价, purchaseprice AS ...
- 自动删除Android工程中无用的资源
开发时间久了, 几个版本迭代之后, 工程中难免留下很多垃圾资源, 造成apk的包很大, 这里介绍一个工具, 可以自动扫描工程中, 没有使用的资源, 然后自动删除: 包括图片, xml, 文本等. 采用 ...
- 【linux基础】ubuntu系统NVIDIA驱动安装
在安装GPU环境下的软件工具,特别是CUDA/CUDNN等,一定要先把GPU环境搭建好. NVIDIA驱动安装会遇到各种问题,真希望黄教主可以将各个工具如何安装使用讲解的更加细致.清楚一些,有时候按照 ...
- 关于matlab中画图放大局部细节的问题
1)需要用得到一个matnify.m文件,下载地址magnify 2)接下来就是如何使用magnify的问题,参见使用 只是在“使用”中的第二步之前首先要用cd进入magnify所在位置.
- 普通Linux用户1分钟上手vi编辑器
*导读:普通用户只要花1分钟看第二部分即可.高级用户请忽略本文* 目录 1. 编辑器之战 2. vi的使用 2.1 vi的3个模式 2.2 vi的3个模式切换 2.3 vi最基本的命令 2.4 vi的 ...
- Python中serial的使用
一.概述 pyserial模块封装了对串口的访问. 二.特性 在支持的平台上有统一的接口. 通过python属性访问串口设置. 支持不同的字节大小.停止位.校验位和流控 ...