1 Enzyme 是什么?
Enzyme
是一类大分子生物催化剂。酶能加快化学反应的速度(即具有催化作用)
— wikipedia
Airbnb开源的 React 测试类库 Enzyme 提供了一套简洁强大的 API,并通过 jQuery 风格的方式进行DOM 处理,开发体验十分友好。不仅在开源社区有超高人气,同时也获得了React 官方的推荐。
— Airbnb.io
Jest 我们上一篇已经说过了,今天主角是Enzyme , 如字面意思,Enzyme 是酶、有催化作用。那么在React 组件测试中和Jest 产生了什么化学?反应呢?
2 课前准备
2.1 项目
这里我们使用 create-react-app
初始化一个项目
npm i -g create-react-app
npx create-react-app enzyme-in-action --use-npm
cd enzyme-in-action
npm start
复制代码
会自动打开浏览器将看到这个页面。
这个是create-react-app
起手式,如果不太了解建议
Create a New React App – React 了解下。
2.2 准备jest 和 enzyme配置
在::package.json:: 中修改 scripts
- "test": "react-scripts test",
+ "test": "jest",
复制代码
在::package.json:: 中增加jest
配置
"jest": {
"transform": {
"^.+\\.jsx?$": "babel-jest",
"^.+\\.svg$": "jest-svg-transformer"
},
"moduleNameMapper": {
"\\.(css|less)$": "identity-obj-proxy"
}
}
复制代码
安装依赖包
npm i -D jest babel-jest babel-core babel-preset-env babel-preset-react enzyme enzyme-adapter-react-16 jest-svg-transformer identity-obj-proxy
复制代码
jest-svg-transformer
和identity-obj-proxy
是为了保证 jsx 文件中的import logo from './logo.svg'
import './App.css'
被正常渲染出来
2.3 背景知识
Enzyme
它提供三种测试方法:- ::shallow::
- ::render::
- ::mount::
wrapper
wrapper是enzyme包装好的类,以供api使用shallow
在单元测试的过程中,浅渲染将一个组件渲染成虚拟DOM对象,并不会渲染其内部的子组件,也不是真正完整的React Render,无法与子组件互动。
3 起手式
修改create-react-app
为我们生成好的::src/App.test.js::
import React from 'react'
import App from './App'
import { configure, shallow } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
configure({ adapter: new Adapter() })
describe(`<App />`, () => {
it('should render App', () => {
const warpper = shallow(<App />)
console.log(warpper.debug())
})
})
复制代码
npm run test
warpper.debug()
已经输出渲染的Dom,这个
warpper
用来我们后面,用jQuery语法来测试。
4 find
测试节点
在::app.js::中增加
<img src={logo} className="App-logo" alt="logo" />
+ <h1>Welcome to React</h1>
<p>
复制代码
现在我们来正式写单测 ::app.test.js::
describe(`测试<App />`, () => {
const warpper = shallow(<App />)
it('1. 包含一个p标签', () => {
expect(warpper.find('p').length).toBe(1)
})
it('2. class为"App-link"的元素能正常被渲染', () => {
expect(warpper.find('.App-link').exists()).toBeTruthy()
})
it('3. header的class为“App-header”', () => {
expect(warpper.find('header').hasClass('App-header')).toBeTruthy()
})
it('4. header有3个子元素', () => {
expect(warpper.find('header').children().length).toBe(4)
})
it('5. 测试H1标签的内容', () => {
expect(warpper.find('h1').text()).toBe('Welcome to React')
})
it('6. 测试image标签class', () => {
expect(warpper.find({ alt: 'logo' }).hasClass('App-logo')).toBeTruthy()
})
})
复制代码
写过jQuery 的同学有没有很熟悉?这里不过多解释。
这里推荐一个VsCode插件 Jest 在每个单元测试前面会有一个icon标示当前是否过测。
5 使用snapshots
测试组件
按照find
的方法测试组件,需要写多少单元测试,jest 为我们提供了一种快照的方式,来对比组件的变化。 安装依赖:
npm i -D enzyme-to-json
复制代码
在::app.test.js::中增加测试
import Adapter from 'enzyme-adapter-react-16'
+ import toJson from 'enzyme-to-json'
复制代码
describe(`测试<App /> snapshots`, () => {
const tree = shallow(<App />)
it('1. 匹配快照', () => {
expect(toJson(tree)).toMatchSnapshot()
})
})
复制代码
npm run test
在命令行中会有
› 1 snapshot written.
Snapshot Summary
› 1 snapshot written from 1 test suite.
复制代码
这时候我们看工程目录
增加了
src/__snapshots__/App.test.js.snap
这个就是jest的快照。jest原生的快照比较复杂,
enzyme-to-json
为我们做了简化。
第一次写toMatchSnapshot 的时候,被创建。当我们修改测试的时候它被更新。
我们来尝试修改一下react 组件 看会有什么事情发生
修改::app.js::
- <h1>Welcome to React</h1>
+ <h1>Welcome to React Jest Enzyme</h1>
复制代码
npm run test
在命令行中会有 错误信息,告诉你哪里发生了变化
tips: 更新快照的命令:
jest --updateSnapshot
在watch 的情况下 按u 更新快照,如果你用的是vscode 那么修改组件的时候会提醒你是否更新。
6 测试含有“props”的组件
首先增加一个<Link>
组件 ::App.js::
export class Link extends PureComponent {
render() {
const { hide, address } = this.props
return hide ? null : <a href={address}>Click</a>
}
}
复制代码
在::app.test.js::中增加测试
describe(`测试<Link />`, () => {
it('1. 测试link组件', () => {
const warpper = shallow(<Link address="https://www.google.com" />)
expect(warpper.props().href).toBe('https://www.google.com')
})
it('2. 测试设置Link props', () => {
const warpper = shallow(<Link />)
expect(warpper.find('a').length).toBe(1)
warpper.setProps({ hide: true })
expect(warpper.find('a').length).toBe(0)
})
})
复制代码
warpper.props()
的结果为
{ href: 'https://www.google.com', children: 'Click' }
复制代码
- 在case :
2. 测试设置Link props
中用warpper.setProps()
动态的给<Link />
设置参数验证组件是否被正常渲染
X 未完待续…
后面还有 :如何测试state ,生命周期,等等。 Jest 没写尽兴,再整理一篇进阶的文章,有小伙伴不清楚什么是集成测试和单元测试,后面整理一篇cypress相关的文章。 秋日的北京周末,开始起雾霾,周末陪周老师备考高级教师资格证,才能坐电脑前写这么长时间。
2010年底来北京,一晃8年过去了。刚来北京的时候无知但无畏,到现在无味且无为。纪念一下这个心情复杂的时刻。望以后无论在什么地方,坦然以对。
— 今天的豆瓣日记
来自豆友分享的专辑? 空中 ベスト・オブ (豆瓣) 灰常好听,虽然夜已深,还是元气满满,开始写第三篇。
技术能力有限,有什么不妥之处请指正。 有什么关于前端方面有疑惑?的方面,可以留言交流,会放到后面的写作计划中。
所有评论(0)