前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React测试框架之enzyme

React测试框架之enzyme

作者头像
xiangzhihong
发布2022-11-30 14:55:05
1K0
发布2022-11-30 14:55:05
举报
文章被收录于专栏:向治洪向治洪

简介

Enzyme是由Airbnb开源的一个React的JavaScript测试工具,使React组件的输出更加容易extrapolate 。Enzyme的API和jQuery操作DOM一样灵活易用,因为它使用的是cheerio库来解析虚拟DOM,而cheerio的目标则是做服务器端的jQuery。Enzyme兼容大多数断言库和测试框架,如chai、mocha、jasmine等。

安装与配置

使用enzyme之前,需要在项目中安装enzyme依赖,安装的命令如下:

代码语言:javascript
复制
npm install --save-dev enzyme

由于React 项目需要依赖React的一些东西,所以请确保以下模块已经安装。

代码语言:javascript
复制
npm install --save react react-dom babel-preset-react

要完成渲染测试,除了enzyme之外,还需要Enzyme Adapter库的支持,由于React 版本的不同,Enzyme Adapter的版本也不一样。适配器和React的对应表如下:

Enzyme Adapter Package

React semver compatibility

enzyme-adapter-react-16

^16.0.0

enzyme-adapter-react-15

^15.5.0

enzyme-adapter-react-14.4

^15.5.0

enzyme-adapter-react-14

^0.14.0

enzyme-adapter-react-13

^0.13.0

enzyme支持三种方式的渲染: shallow:浅渲染,是对官方的Shallow Renderer的封装。将组件渲染成虚拟DOM对象,只会渲染第一层,子组件将不会被渲染出来,因而效率非常高。不需要DOM环境, 并可以使用jQuery的方式访问组件的信息; render:静态渲染,它将React组件渲染成静态的HTML字符串,然后使用Cheerio这个库解析这段字符串,并返回一个Cheerio的实例对象,可以用来分析组件的html结构。 mount:完全渲染,它将组件渲染加载成一个真实的DOM节点,用来测试DOM API的交互和组件的生命周期,用到了jsdom来模拟浏览器环境。

常用函数

enzyme中有几个比较核心的函数需要注意,如下:

  • simulate(event, mock):用来模拟事件触发,event为事件名称,mock为一个event object;
  • instance():返回测试组件的实例;
  • find(selector):根据选择器查找节点,selector可以是CSS中的选择器,也可以是组件的构造函数,以及组件的display name等;
  • at(index):返回一个渲染过的对象;
  • get(index):返回一个react node,要测试它,需要重新渲染;
  • contains(nodeOrNodes):当前对象是否包含参数重点 node,参数类型为react对象或对象数组;
  • text():返回当前组件的文本内容;
  • html(): 返回当前组件的HTML代码形式;
  • props():返回根组件的所有属性;
  • prop(key):返回根组件的指定属性;
  • state():返回根组件的状态;
  • setState(nextState):设置根组件的状态;
  • setProps(nextProps):设置根组件的属性;

使用

为了方便讲解Enzyme测试的用法,我们首先新建一个enzyme.js的测试文件。代码如下:

代码语言:javascript
复制
import React from 'react'

const Example=(props)=>{
    return (<div>
        <button>{props.text}</button>
    </div>)
}
export default Example

浅渲染shallow

前面说过,Shallow Rendering用于将一个组件渲染成虚拟DOM对象,但是只渲染第一层,不渲染所有子组件,所以处理速度非常快。并且它不需要DOM环境,因为根本没有加载进DOM。

为了进行浅渲染shallow测试,我们新建一个名为enzyme.test.js的测试文件。

代码语言:javascript
复制
import React from 'react'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import Example from '../enzyme'

const {shallow}=Enzyme

Enzyme.configure({ adapter: new Adapter() })

describe('Enzyme shallow', function () {
    it('Example component', function () {
        const name='按钮名'
        let app = shallow(<Example text={name} />)
       let btnName=app.find('button').text();
       console.log('button Name:'+btnName)
    })
})

执行yarn test命令,会看到如下的运行结果:

在这里插入图片描述
在这里插入图片描述

为了避免每个测试文件都这么写,我们可以再test目录下新建一个配置文件enzyme_config.test.js。文件内容如下:

代码语言:javascript
复制
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({
    adapter: new Adapter(),
});

export default Enzyme;

然后,在test目录下新建一个文件setup.js:

代码语言:javascript
复制
import jsdom from 'jsdom';
const { JSDOM } = jsdom;

if (typeof document === 'undefined') {
    const dom=new JSDOM('<!doctype html><html><head></head><body></body></html>');
    global.window =dom.window;
    global.document = global.window.document;
    global.navigator = global.window.navigator;
}

修改我们的package.json中的测试脚本为如下配置:

代码语言:javascript
复制
 "scripts": {
    "test": "mocha --require babel-core/register --require ./test/setup.js"
  }

现在,我们的shallow测试代码可以改为:

代码语言:javascript
复制
import React from 'react'
import Enzyme from './enzyme.config';
import Example from '../enzyme'

const {shallow}=Enzyme

describe('Enzyme shallow', function () {
    it('Example component', function () {
        const name='按钮名'
        let app = shallow(<Example text={name} />)
        let btnName= app.find('button').text()
        console.log('button Name:'+btnName)
    })
})

完全渲染mount

mount渲染用于将React组件加载为真实DOM节点。然而,真实DOM需要一个浏览器环境,为了解决这个问题,我们可以用到jsdom,也就是说我们可以用jsdom模拟一个浏览器环境去加载真实的DOM节点。 首先,使用下面的命令安装jsdom模拟浏览器环境,安装命令如下:

代码语言:javascript
复制
npm install --save-dev jsdom

然后我们添加一个完全渲染的测试代码:

代码语言:javascript
复制
import React from 'react'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import Example from '../src/example'

const {shallow,mount}=Enzyme

Enzyme.configure({ adapter: new Adapter() })

describe('Enzyme mount的DOM渲染(Full DOM Rendering)中', function () {
  it('Example组件中按钮的名字为子组件Sub中span的值', function () {
    const name='按钮名'
    let app = mount(<Example text={name} />)

    const buttonObj=app.find('button')
    const spanObj=app.find('span')

    console.info(`查找到button的个数:${buttonObj.length}`)
    console.info(`查找到span的个数:${spanObj.length}`)

   buttonObj.text(),spanObj.text()
  })
})

静态渲染render

render静态渲染,主要用于将React组件渲染成静态的HTML字符串,然后使用Cheerio这个库解析这段字符串,并返回一个Cheerio的实例对象,可以用来分析组件的html结构。针对前面的enzyme.js文件,我们的静态渲染测试的代码如下:

代码语言:javascript
复制
import React from 'react'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import Example from '../enzyme'

const {shallow,mount,render}=Enzyme

Enzyme.configure({ adapter: new Adapter() })

describe('Enzyme render test', function () {
    it('Example render', function () {
        const name='按钮名'
        let app = render(<Example text={name} />)

        const buttonObj=app.find('button')
        const spanObj=app.find('span')

        console.info(`查找到button的个数:${buttonObj.length}`)
        console.info(`查找到span的个数:${spanObj.length}`)

        buttonObj.text(),spanObj.text()
    })
})

执行上面的代码,测试结果如下:

在这里插入图片描述
在这里插入图片描述

对比

为了对比这三大测试框架,我们可以对比看一下:

代码语言:javascript
复制
describe('shallow vs render vs mount', function () {
    it('测试 shallow 500次', () => {
        for (let i = 0; i < 500; i++) {
            const app = shallow(<Example/>)
            app.find('button').text()
        }
    })

    it('测试render500次', () => {
        for (let i = 0; i < 500; i++) {
            const app = render(<Example/>)
            app.find('button').text()
        }
    })

    it('测试mount500次', () => {
        for (let i = 0; i < 500; i++) {
            const app = mount(<Example/>)
            app.find('button').text()
        }
    })
})

运行结果如下图:

在这里插入图片描述
在这里插入图片描述

如上图,shallow是最快的,这是因为shallow的局限性,只渲染第一层,不渲染所有子组件。事实证明,render的效率是mount的两倍。 那么问题来了,mount存在的价值是什么?当然是有价值的,shallow和mount因为都是dom对象的缘故,所以都是可以模拟交互的。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-11-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 安装与配置
  • 常用函数
  • 使用
    • 浅渲染shallow
      • 完全渲染mount
        • 静态渲染render
          • 对比
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档