-
Notifications
You must be signed in to change notification settings - Fork 0
Description
测试框架 jest
当你搜索jest时,你看到这么一句话:Jest · 令人愉快的JavaScript 测试(Delightful JavaScript Testing)
为什么这样说:
1.安装简单,只要npm install --save-dev jest 就可以开始写单元测试
2.自带了断言库,mock,测试报告,
3.还有一个非常棒的快照(Snapshot)
enzyme
它是react一个测试工具,可以不需要起动赖浏览器,来渲染react,它的api有点像jQuery api,使操作起来更方便。
enzyme分为三种渲染方式:
-
mount
- 用于将React组件加载为真实DOM节点。
- 可以实现 Full Rendering。比如说当我们需要对DOM API交互或者你需要测试组件的整个生命周期(如: componentDidMount)的时候,可以使用这个方法。需要注意的是,由于需要渲染成真实的dom节点,那么就需要测试环境对DOM API有支持。jest在内部使用了 jsdom 去模拟了DOM环境,所以我们就可以不用写一个setup.js文件去mock那些全局变量了
-
render
方法将React组件渲染成静态的HTML字符串,然后分析这段HTML代码的结构,返回一个对象。它跟shallow方法非常像,主要的不同是采用了第三方HTML解析库Cheerio,它返回的是一个Cheerio实例对象。
-
shallow(渲染)
将一个组件渲染成虚拟DOM对象,但是只渲染第一层,不渲染所有子组件,所以处理速度非常快。它不需要DOM环境,因为根本没有加载进DOM
一般我们常用的mount,和shallow
需要注意的是mount是依赖jsdom的
jsdom中有坑,请注意
jsdom模拟了浏览器的dom渲染,基本上也web api保持同步, ==但它有许多缺少的API==,
有两个功能不支持:
- Navigation
`点击链接或导航或使用location.href去更改全局对象`
- Layout
Layout不支持,不就不计算css可视化布局的元素的位置,比如:clientWidth、offsetTop、getBoundingClientRects(),innerText之类的属性,如果想测试这些可以mock,或者使用phantomJS、puppeteer之类的工具测试
- ==innerText==
先问大家一下,你们知道innerText和textContent的区别吗 - innerText是被微软引进的,在早期的firefox和chrome都不支持
- innerText是依赖布局渲染的,代码为证
<div id="t"><div>lions,
tigers</div><div style="visibility:hidden">and bears</div></div>
innerText输出:lions, tigers
textContent输出:
lions,
tigersand bears
<div contenteditable>
A
mind
needs books<br>as a sword needs a whetstone<p>if it is to <span style="display: block">keep</span> its edge.
</p>
</div>
<div>
innerText<textarea id="innerText" style="display: inline-block"></textarea>
</div>
<div>
textContent<textarea id="textContent" style="display: inline-block"></textarea>
</div>
//css
div, textarea {
display: inline-block;
vertical-align: top;
width: 250px;
height: 160px;
margin-right: 10px;
}
result
innerText
A mind needs books
as a sword needs a whetstone
if it is to
keep
its edge.
textContent
A
mind
needs booksas a sword needs a whetstoneif it is to keep its edge.
innerText几乎精确地表示文本在页面上的显示方式,
textContent 忽略了span标签上的display:block
react 单元测试中遇到的坑
- jsdom不支的部分的怎么测试,改代码吗,想过,可工程量太大,算了吧,当然你的组件如果没有使用ReactDOM,以下你可以跳过
document.body.innerHTML = '<div id="mounter" />';
wrapper = mount(commpent,{ attachTo: document.getElementById('mounter'))
wrapper.instance().node.getBoundingClientRect = jest.fn(() => {
return {
bottom: 100, height: 28, left: 0, right: 0, top: -50, width: 195,
};
});
Object.defineProperty(wrapper.instance().node, "innerText", {
value: "1dddddddddddddddddddddddddddddddddddddd",
})
Object.defineProperty(wrapper.instance().node, "clientWidth", { value: 50 })
Object.defineProperty(wrapper.instance().node, "scrollWidth", { value: 100 })
-
snapshot 在使用jest推荐的react-test-renderer时可能过不去,可以解析成jest支持的格式,
https://www.npmjs.com/package/enzyme-to-json -
react-test-renderer 里不支持ReactDOM的方法,比较如:ReactDOM.findDOMNode,会报出Invariant Violation: getNodeFromInstance: Invalid argument.
-
react-test-renderer
renderer.create(component) component 必需组件,不是mount或shandow之后的,比较麻烦
-
ReactTestRenderer doesn't work with refs or ReactDOM.findDOMNode facebook/react#7371