Jest + Enzyme React 组件测试实践
≈
最近把组件测试接入到日常开发,提高了项目代码健壮性,可维护性。本人也从0到1收获了组件测试的经验。
本文总结一下最近两周 组件测试 相关的研究,包括:
- Jest + Enzyme 的基本介绍
- Jest + Enzyme 的实践
- Jest 原理浅析
- Jest 生态 & 未来
文章目录
- 为什么选择Jest & Enzyme?
- 1. Jest
- 2. Enzyme
- Jest + Enzyme 的实践
- 1. 配置开发
- 2. 调试
- 3. Transform
- 4. Mock
- Jest 原理浅析
- 1. Jest的本质与Jasmine
- 2. Jest Own Test Runner与Flux
- Jest 生态 & 未来
为什么选择Jest & Enzyme?
1. Jest
Jest 是一套Facebook家背书的测试框架。
实际上,编写一个测试用例,我们需要以下准备:
- 一个测试类库
- 一个断言库(assertion)
- 一个测试执行环境(environment)
- 其他(function or module mock, snapshot etc…)
Jest是包含以上(1234)四合一的一款测试框架。
- Jest内置了jsDOM和Node的执行环境。默认开启面向浏览器端的jsDOM环境。
- Jest内置一套断言库,和Jasmine相同语法。
- Jest自带函数和模块的Mock能力;自己发明了一个专门针对组件测试的快照(snapshot)测试;Jest支持热更新;Jest支持多线程测试。
当然Jest也有一些劣势。
2019年另一款很火的测试框架Mocha,自身不带断言库,也不带Func/Module Mock,集成社区相对成熟的断言库Chai和mock库SinonJS之后,非常强大。Chai断言库相较于Jest内置的断言库API更加丰富更加强大,SinonJS的mock的API也十分完善。而且Mocha的不带其他杂七杂八功能的理念,让它十分具有可配置性。
但是最终选择Jest原因有以下几点:
1. 没有最牛逼的框架,只有最合适的框架。
- 对于组件库的项目,我们对于组件测试的需求非常大,包括组件API的测试和组件呈现效果的测试。Jest自带的snapshot的测试,很亮眼,会把组件渲染的DOM解析成JSON作为快照保存,下一次再获得新的DOM的JSON序列,与旧的序列进行对比,保证组件的呈现的稳定性。
- 组件库的测试很少涉及到网络请求,server端测试,目前是一个纯浏览器端的测试需求。所以Jest自带的断言能力,mock能力够用。而且据我所知,Jest是有一个叫做jest-extend的断言库扩展包。甚至,自己手写就好了。
2. 更简单的配置,更快地上手。
- 实现一个snapshot,只需一句话:expect(component).toMatchSnapshot(),很简单。
- 断言库来自Jasmine,很精炼,够用,简单。
3. 实际上Jest的可配置化也非常强。
- Jest有自己的生态建设(Jest Community)。目前可以配置更加强大的断言扩展,更加灵活的运行环境,甚至还有snapshot使用svg保存的拓展(实际上Jest有倾向做真正的视觉测试,像素比较???好酷鸭)
- Jest自身的配置文件可配置项非常多。我就通过Jest的config配置文件把一个storybook文章生成文件mock成测试用例了哈哈(理论上讲,任何文件都可以变成测试文件)。
4. MVVM框架支持度
- 目前Jest支持市面上主流的开发框架:Vue,React,Angular。babel支持的就是它支持的,因为它提供transform功能。使用jest-babel插件然后利用本地babel配置做文件转换皆可。(也就是说,理论上讲,支持市面上拥有babel转换插件的任何MVVM框架)。
2. Enzyme
Enzyme是Airbnb家的React组件用例测试渲染库。
实际上React官方对于React components的测试有暴露一些库:
react-dom/test-utils
: 拥有一些看一遍也不知道怎么用的API。react-test-render
:可以无渲染环境的基础下,通过shallow渲染拿到WHATWG规范的DOM树结构。React团队利用这个库和Jest团队一起努力打造了React的snapshot test。
Enzyme底层就是封装了以上两个库,却拥有简单精巧的API,打败了React家自带的test render(API设计的力量!React家也一直在安利Enzyme…)。它一共有三个大API:
- shallow:浅渲染。只渲染根级,不渲染子集,它就是封装的
react-test-render/shallow
,生成的是虚拟DOM。 - mount:完整DOM渲染。拥有DOM API交互能力。
- render:静态渲染。用来分析HTML结构。snapshot请使用这个API。
Enzyme对于以上三种渲染方式都有详细介绍的小API查询。
最终选择Enzyme原因很明确了,这是目前为止最简单上手,功能最强大的React components render库了。
Jest + Enzyme 的实践
1. 配置开发
- 一篇入门:https://medium.com/codeclan/testing-react-with-jest-and-enzyme-20505fec4675
2. 调试
- 一篇troubleShoot: https://jestjs.io/docs/en/troubleshooting
Jest一些十分有用的Config:
3. Transform
Jest实际上可以测试任意文件:只要你的文件可以通过transform,得到的结果可以被Jest的断言库语法解析。因此一个Markdown,txt等等文件都可以被测试。
4. Mock
Jest默认会mock所有node_modules目录下的依赖文件。我们既可以在config配置文件中配置全局mock规则,也可以在测试用例编写的时候mock某一个function或module。
Jest在内部是这样处理的:拿到file code之后,包一层函数,传入重写的require,export函数。把mock的代码接在code前面。然后一起执行?。
Jest 原理浅析
Jest一共有30多个package,从零开始看你会疯掉。如果想要研究的话,推荐看去年底,Jest官方发布的架构原理视频:https://jestjs.io/docs/en/architecture, 粗略地讲了其中几个重要的包的功能,以及一个测试用例如何被初始化,添加Mock,调度,最终执行的过程。核心内容就是下面这张图。
1. Jest的本质与Jasmine
Jest本身其实是基于Jasmine库之上封装的,Jest的断言库和具体的测试用例执行过程都是Jasmine做的。Jest本身做的是以下事情:
- CI封装
- code transform
- 更抽象的project config
- 多线程调度通信
- jsdom和node以及可以灵活配置的envrionment
- snapshot
- …
(现在还会出现栈溢出的问题,对此Jest的做法是加一个100ms的timeout解决我的天。我在用Jest的时候,snapshot稳稳栈溢出,需要加一个enzyme-to-json/serializer
解决。
Jasmine是BDD(behavior-driven development行为驱动开发)的Javascript测试框架。Jasmine非常轻量,本身只有20KB。Jest目前的断言语法都是来自于Jasmine。它定义有如下两种语法:
- describe:内部定义为一个Suite。是一堆测试块的集合。
- it:内部定义为一个Spec。是一个测试块。
以下是一段测试用例代码:
describe("A suite", function() {it("contains spec with an expectation", function() {expect(true).toBe(true);});});
非常语义化,不用看API都能看懂,类似Regular English,这就是BDD。
它拿到用户配置,首先会正则匹配到所有符合要求的文件,抽取出一颗树processTree,因为它支持Suite的嵌套,所以它会先遍历这棵树,做一次order更新,然后用捕获冒泡的方式从树根遍历到树叶再从树叶的father节点再遍历到树根,在它的context下执行测试用例。目的是把测试report通知到所有祖先Suite,最后打出一份Report。(但是,你不要以为Jasmine体积小就好阅读了,Jasmine的源码就是一坨回调地狱。我认为它可以选择重构。)
2. Jest Own Test Runner与Flux
Jest独立出来的其中一个包,就是图中所说的jest-circus。我们可以通过配置选择circus而不是jasmine, 它将要替代Jasmine???
Circus is a flux-based test runner for Jest that is fast, easy to maintain, and simple to extend.
官方说Circus更加快,好维护,易拓展。它支持用户接入任何自定义的执行环境。
import {NodeEnvironment} from 'jest-environment-node';
import {Event, State} from 'jest-circus';// 自定义的环境
class MyCustomEnvironment extends NodeEnvironment {//...handleTestEvent(event: Event, state: State) {if (event.name === 'test_start') {// ...}}
}
它使用了Flux的思想,自己维护了一个state,然后通过事件的Emitter去更新state,没有回调地狱的存在。所以它说:
Mutating event or state data is currently unsupported and may cause unexpected behavior or break in a future release without warning. New events, event data, and/or state data will not be considered a breaking change and may be added in any minor release.
它只支持不可变数据和函数。
Jest 生态 & 未来
Jest有自己的平台https://jestjs.io/docs/en/jest-platform,提供了一些工具函数。
未来的话,Jest有倾向:
- 在snapshot的基础上做视觉测试。
- 多项目测试。比如同时用jest起一个server端和browser端的测试。
- 解决测试时间问题。
Jest + Enzyme React 组件测试实践相关推荐
- enzyme react 组件测试
enzyme 简单实践 enzyme 主要用于 React 组件测试 文档链接:https://enzymejs.github.io/enzyme/ https://www.npmjs.com/pac ...
- React组件设计实践总结05 - 状态管理
今天是 520,这是本系列最后一篇文章,主要涵盖 React 状态管理的相关方案. 前几篇文章在掘金首发基本石沉大海, 没什么阅读量. 可能是文章篇幅太长了?掘金值太低了? 还是错别字太多了? 后面静 ...
- React组件库实践:React + Typescript + Less + Rollup + Storybook
背景 原先在做低代码平台的时候,刚好有搭载React组件库的需求,所以就搞了一套通用的React组件库模版.目前通过这套模板也搭建过好几个组件库. 为了让这个模板更干净和通用,我把所有和低代码相关的代 ...
- angular select设置默认选中_改进 Angular + Jest 项目中组件测试的调试
@angular-extensions/pretty-html-log 原文链接medium.com原作者:Kevin Kreuzermedium.com 译者: 知乎用户www.zhihu.c ...
- Vite + React 组件开发实践
简介: 毫不夸张的说,Vite 给前端带来的绝对是一次革命性的变化.或者也可以说是 Vite 背后整合的 esbuild . Browser es modules.HMR.Pre-Bundling 等 ...
- JavaScript 测试系列实战(一):使用 Jest 和 Enzyme 测试 React 组件
你或许早已经知道"单元测试""端到端测试"这些名词,但从未真正付诸实践.在这一系列实战教程中,我们将手把手带你掌握 Jest.Enzyme.Cypress 等测 ...
- 使用 Jest 和 Enzyme 测试 React 组件
type: FrontEnd title: Testing React components with Jest and Enzyme link: hackernoon.com/testing-rea ...
- 全网最细:Jest+Enzyme测试React组件(包含交互、DOM、样式测试)
介绍 Jest是目前前端工程化下单元测试火热的技术栈,而Enzyme的支持提供了Jest测试React业务.组件的能力,下面来介绍一下React组件测试的一些实际场景. 1. 测试依赖包 " ...
- 怎样写一个具有异步交互的React组件的单元测试
关于前端React组件测试(jest,Enzyme),网上有大量的入门文章,可以看看,但如果你确实想了解前端自动化测试,个人更推荐看官方的文档和一些比较官方的测试案列,这里推荐两个: enzyme官方 ...
最新文章
- LeetCode实战:两数相加
- vivo 互联网业务就近路由技术实战
- LeCun:现在还没有真正的AI系统,机器与生物系统差远了
- python绘制如下图形、小三角形边长20_在编程中发现数学之美——使用Python小龟绘制多边形...
- sccm 2007 r2 step by step 之十五 补丁管理
- 【ElasticSearch】IK分词加入标点符号
- UI网格,提升效率,爱上做设计
- dnp服务器未响应,PTP时间戳精度
- 高效使用电脑,Fence和Direct Folder
- cnblog之初来乍到
- keil 4c语言 百度经验,Keil教程(4)
- 计算机桌面图标乱了,如何解决电脑桌面图标乱跑的问题
- E盾网络验证介绍以及教程分享
- 弹幕助手连接不到服务器,小葫芦obs弹幕助手怎么用 OBS弹幕助手使用教程
- 野火STM32F429学习笔记
- 【毕业设计】【周记】STGCN模型的改进和可视化
- C语言揭秘二战德军的顶级加解密技术——恩格玛机!
- mysql 表 忽略大小写_mysql表名忽略大小写配置方法详解
- 超短线炒黄金技巧你掌握到位了吗
- 怎么退出自适应巡航_一口气搞懂自适应巡航ACC
热门文章
- java 超链接_java 将字符串中的网络连接加上超链接
- 什么是oAuth(开放式授权)?OAUTH协议特点和授权流程?
- 用python制作一个课堂点名器
- 原生table:表格table中thead固定,tbody超出高度出现滚动条
- ppt制作读书笔记(未完)
- 哈工大 大数据算法 频度矩估计-Basic AMS算法
- breeze 可视安装 k8s 集群
- #python遍历列表(有源码有截图)
- Nextracker冲刺美股:拟募资5亿美元 下周纳斯达克上市
- 微信第三方平台【一】获取验证票据 component_verify_ticket,授权结果接收