Jest
是一个 JavaScript
测试运行器。它允许你使用 jsdom
操作 DOM
。尽管 jsdom
只是对浏览器工作表现的一个近似模拟,对测试 React
组件来说它通常也已经够用了。Jest
有着十分优秀的迭代速度,同时还提供了若干强大的功能,比如它可以模拟 modules 和 timers 让你更精细的控制代码如何执行。Create React App
已经集成Jest
。
配置
保持 create react app 基本配置不变:
"scripts": {
"test": "react-app-rewired test --env=jsdom --coverage",
},
此处多了--coverage
,这个命令会打印出当前测试代码的覆盖率,似乎只在配置如下才生效:
"scripts": {
"test": "jest --coverage",
},
运行测试命令,不配置--coverage
也是可运行的。yarn test
安装渲染组件快照模块
测试 CRA 框架下的组件只需要安装react-test-renderer
来渲染快照。yarn add --dev react-test-renderer
测试代码的编写
拿我项目中一个真实的组件来做实例,首先创建一个.jsx组件:
import React, { Component } from 'react';
import LogoMsg from './LogoMsg';
// 多状态组件
// type => loading:加载 empty:无数据 nonet:无网络 404:路由错误 error:其他错误 content:显示子布局
// msg => 错误信息
class Multistate extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
var multistate = null;
switch (this.props.type) {
case "load":
case "loading":
multistate = (<LogoMsg load msg={this.props.msg || '数据加载中'} />)
break;
case 'empty':
multistate = (<LogoMsg alt="页面空" msg={this.props.msg || '当前页面无数据'} />)
break;
case "nonet":
multistate = this.props.msg || "当前网络异常,请检查网络"
break;
case "404":
multistate = "404 the page is not found.";
break;
case "error":
multistate = (<LogoMsg alt="页面错误" msg={this.props.msg || '存在异常,无法正常访问'} />)
break;
default:
}
return (<>
{
(multistate) ?
(<div className={`default-container multistate ${this.props.child ? 'child' : ''}`}>
{multistate}
</div>)
: this.props.children
}
</>);
}
}
export default Multistate;
这是一个提供页面显示不同状态的布局视图,通过props.type
参数控制显示不同的页面内容,似乎路由也能做到,但是架不住我懒。现在用单元测试验证代码逻辑的可行性,创建一个名为Multistate.test.js
的文件,Jest会自动寻找.test.js
文件执行里面的测试代码。Multistate.test.js
编写测试内容:
import React from 'react';
import renderer from 'react-test-renderer';
import Multistate from '../../components/Multistate';
it('Multistate 显示内容', () => {
const tree = renderer
.create(<Multistate type="content"><div>真正需要的内容</div></Multistate>)
.toJSON();
expect(tree).toMatchSnapshot();
});
it('Multistate 显示错误', () => {
const tree = renderer
.create(<Multistate type="error"><div>真正需要的内容</div></Multistate>)
.toJSON();
expect(tree).toMatchSnapshot();
});
it('Multistate 显示空页面', () => {
const tree = renderer
.create(<Multistate type="empty"><div>真正需要的内容</div></Multistate>)
.toJSON();
expect(tree).toMatchSnapshot();
});
it('Multistate 显示加载', () => {
const tree = renderer
.create(<Multistate type="load"><div>真正需要的内容</div></Multistate>)
.toJSON();
expect(tree).toMatchSnapshot();
});
it('Multistate 显示无网络', () => {
const tree = renderer
.create(<Multistate type="nonet"><div>真正需要的内容</div></Multistate>)
.toJSON();
expect(tree).toMatchSnapshot();
});
it('Multistate 显示404', () => {
const tree = renderer
.create(<Multistate type="404"><div>真正需要的内容</div></Multistate>)
.toJSON();
expect(tree).toMatchSnapshot();
});
it('Multistate 什么都不传', () => {
const tree = renderer
.create(<Multistate><div>真正需要的内容</div></Multistate>)
.toJSON();
expect(tree).toMatchSnapshot();
});
共测试7个不同的状态,在控制台运行命令:yarn test
执行结果如下
测试组件时在这里看不出什么问题,我想也许是我的姿势不对,按官方提供的文档来确定,这里应该要出现历史测试比对结果的,但是我一直没有出现。这里有没有没有关系, 测试组件快照时,Jest会在.test.js
同目录下创建文件夹__snapshots__
,并生成文件Multistate.test.js.snap
,文件内容:
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Multistate 什么都不传 1`] = `
<div>
真正需要的内容
</div>
`;
exports[`Multistate 显示404 1`] = `
<div
className="default-container multistate "
>
404 the page is not found.
</div>
`;
exports[`Multistate 显示内容 1`] = `
<div>
真正需要的内容
</div>
`;
exports[`Multistate 显示加载 1`] = `
<div
className="default-container multistate "
>
<div
className="vertical-layout center empty-container"
>
<svg
className="am-icon am-icon-loading am-icon-lg"
color="#06BB06"
>
<use
xlinkHref="#loading"
/>
</svg>
<div
style={
Object {
"marginTop": "10px",
}
}
>
数据加载中
</div>
</div>
</div>
`;
exports[`Multistate 显示无网络 1`] = `
<div
className="default-container multistate "
>
当前网络异常,请检查网络
</div>
`;
exports[`Multistate 显示空页面 1`] = `
<div
className="default-container multistate "
>
<div
className="vertical-layout center empty-container"
>
<img
alt="页面空"
src="empty.png"
style={
Object {
"height": "139.5px",
"marginBottom": "10px",
"width": "168px",
}
}
/>
<div
style={
Object {
"marginTop": "10px",
}
}
>
当前页面无数据
</div>
</div>
</div>
`;
exports[`Multistate 显示错误 1`] = `
<div
className="default-container multistate "
>
<div
className="vertical-layout center empty-container"
>
<img
alt="页面错误"
src="empty.png"
style={
Object {
"height": "139.5px",
"marginBottom": "10px",
"width": "168px",
}
}
/>
<div
style={
Object {
"marginTop": "10px",
}
}
>
存在异常,无法正常访问
</div>
</div>
</div>
`;
Jest会把dom信息保存到Multistate.test.js.snap
文件中,从这里可以直观的查看到每种测试结果,发现问题即修改。如果需要删除Multistate.test.js.snap
文件信息重新测试只需要在控制台输入命令:yarn test -u
即可。