jest与enzyme对react项目自动化测试

发布 : 2018-07-07 分类 : JavaScript 浏览 :

jest与enzyme对react项目自动化测试


基于jest和enzyme的特性,我们对一个react项目,可以进行以下几类测试。

组件UI测试

snapshot可以测试到组件的渲染结果是否符合预期,预期就是指你上一次录入保存的结果,toMatchSnapshot方法会去帮你对比这次将要生成的结构与上次的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
it('use arrowPointAtCenter', () => {
const wrapper = render(
<div>
<Tooltip placement="topLeft" title="Prompt Text">
<Button>Align edge / 边缘对齐</Button>
</Tooltip>
<Tooltip placement="topLeft" title="Prompt Text" arrowPointAtCenter>
<Button>Arrow points to center / 箭头指向中心</Button>
</Tooltip>
</div>
);
expect(toJson(wrapper)).toMatchSnapshot();
})

dom交互测试: jest+enzyme

enzyme有3种渲染方式:render、mount、shallow

render采用的是第三方库Cheerio的渲染,渲染结果是普通的html结构,对于snapshot使用render比较合适。

shallow和mount对组件的渲染结果不是html的dom树,而是react树,如果你chrome装了react devtool插件,他的渲染结果就是react devtool tab下查看的组件结构,而render函数的结果是element tab下查看的结果。

这些只是渲染结果上的差别,更大的差别是shallow和mount的结果是个被封装的ReactWrapper,可以进行多种操作,譬如find()、parents()、children()等选择器进行元素查找;state()、props()进行数据查找,setState()、setprops()操作数据;simulate()模拟事件触发。

shallow只渲染当前组件,只能能对当前组件做断言;mount会渲染当前组件以及所有子组件,对所有子组件也可以做上述操作。一般交互测试都会关心到子组件,我使用的都是mount。但是mount耗时更长,内存啥的也都占用的更多,如果没必要操作和断言子组件,可以使用shallow。

api

.find(selector): 查找当前包装器的呈现树中与提供的选择器匹配的每个节点。
.get(index):返回指定位置的子组件的DOM节点
.at(index):返回指定位置的子组件
.first():返回第一个子组件
.last():返回最后一个子组件
.type():返回当前组件的类型
.text():返回当前组件的文本内容
.html():返回当前组件的HTML代码形式
.props():返回根组件的所有属性
.prop(key):返回根组件的指定属性
.state([key]):返回根组件的状态
.setState(nextState):设置根组件的状态
.setProps(nextProps):设置根组件的属性

shallow

shallow方法就是官方的shallow rendering的封装。

Shallow renders the current node and returns a shallow wrapper around it.

NOTE: can only be called on wrapper of a single node.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Bar() {
return (
<div>
<div className="in-bar" />
</div>
);
}

function Foo() {
return (
<div>
<Bar />
</div>
);
}

const wrapper = shallow(<Foo />);
expect(wrapper.find('.in-bar')).to.have.length(0);
expect(wrapper.find(Bar)).to.have.length(1);
expect(wrapper.find(Bar).shallow().find('.in-bar')).to.have.length(1);

render

render方法将React组件渲染成静态的HTML字符串,然后分析这段HTML代码的结构,返回一个对象。它跟shallow方法非常像,主要的不同是采用了第三方HTML解析库Cheerio,它返回的是一个Cheerio实例对象。

1
2
3
4
5
6
7
8
import {render} from 'enzyme';

describe('Enzyme Render', function () {
it('Todo item should not have todo-done class', function () {
let app = render(<App/>);
expect(app.find('.todo-done').length).to.equal(0);
});
});

mount

A method that re-mounts the component. This can be used to simulate a component going through an unmount/mount lifecycle.

mount方法用于将react组件加载为真实的dom节点。

语法:

function mount(node, options) {
return new _ReactWrapper2‘default’;
}

1
2
3
4
5
6
7
8
9
10
import {mount} from 'enzyme';

describe('Enzyme Mount', function () {
it('Delete Todo', function () {
let app = mount(<App/>);
let todoLength = app.find('li').length;
app.find('button.delete').at(0).simulate('click');
expect(app.find('li').length).to.equal(todoLength - 1);
});
});

上面代码中,find方法返回一个对象,包含了所有符合条件的子组件。在它的基础上,at方法返回指定位置的子组件,simulate方法就在这个组件上触发某种行为。

对于交互事件的测试

使用simulate进行模拟事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
const { count } = this.state;
return (
<div>
<div className={`clicks-${count}`}>
{count} clicks
</div>
<a href="url" onClick={() => { this.setState({ count: count + 1 }); }}>
Increment
</a>
</div>
);
}
}

const wrapper = mount(<Foo />);

expect(wrapper.find('.clicks-0').length).to.equal(1);
wrapper.find('a').simulate('click');
expect(wrapper.find('.clicks-1').length).to.equal(1);

也可以对相应的组件属性的事件显示触发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
it("named 'SnackBar' exists", () => {
const event = {
keyCode: 1
};
enzymeWrapper
.find("Button[label='DOWNLOAD']")
.props()
.onClick(event);
enzymeWrapper
.find("ConfirmDialog")
.props()
.onClickConfirm();
enzymeWrapper
.find("Snackbar")
.props()
.onRequestClose();
});

上述代码测试了点击download按钮后会弹出一个dialog,其中有确定按钮(onClickConfirm)与取消按钮(onClickCancel),点击确定后,文件download之后会有message的反馈。

本文作者 : 对六
原文链接 : http://duiliuliu.github.io/2018/07/07/2018-07-07-jest与enzyme对react项目自动化测试/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

你我共勉!

微信

微信

支付宝

支付宝

留下足迹