网易云团队前端单元测试技术方案总结(三)
Jest 是 facebook 出的一个完整的单元测试技术方案,集 测试框架, 断言库, 启动器, 快照,沙箱,mock工具于一身,也是 React 官方使用的测试工具。Jest 和 Jasmine 具有非常相似的 API ,所以在 Jasmine 中用到的工具在 Jest 中依然可以很自然地使用。可以近似看作 Jest = JSDOM 启动器 + Jasmine 。
虽然 Jest 提供了很丰富的功能,但是并没有内置 ES6 支持,所以依然需要根据不同运行时对代码进行转换,由于 Jest 主要运行在 Node 中,所以需要使用 babel-jest 将 ES Module 转换成 CommonJS 。
Jest 的默认配置:
npm install jest --save-dev
npx jest --init
√ Would you like to use Jest when running "test" script in "package.json"? ... yes
√ Would you like to use Typescript for the configuration file? ... no
√ Choose the test environment that will be used for testing ? jsdom (browser-like)
√ Do you want Jest to add coverage reports? ... no
√ Which provider should be used to instrument code for coverage? ? babel
√ Automatically clear mock calls and instances between every test? ... yes在 Node 或 JSDOM 下增加 ES6代码的支持
npm install jest-babel @babel/core @babel/preset-env// .babelrc
{
"presets": ["@babel/preset-env"]
} // jest.config.js
// 下面两行为默认配置,不写也可以
{
+ testEnvironment: "jsdom",
+ transform: {"\\.sx?$": "babel-jest"}
}使用 Jest 生成测试报告:
对于 React 和 TypeScript 支持也可以通过修改 babel 的配置解决。
npm install @babel/preset-react @babel/preset-typescript --save-dev
// .babrlrc
{
"presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"]
} Jest 在真实浏览器环境下测试
目前 Jest 不支持直接在真实浏览器中进行测试,其默认的启动器只提供了一个 JSDOM 环境,在浏览器中进行单元测试目前只有 Karma 方案能做到,所以也可以使用 Karma + Jest 方案实现,但是不建议这么做,因为 Jest 自身太重,使用 Karma + Jasmine 能达到基本一样的效果。
另外还有一个比较流行的 E2E 方案 Jest + Puppeteer,由于 E2E不属于单元测试范畴,这里不再展开。
Jest 工具链总结:
· Node 环境下测试 : Jest + babel
· JSDOM 测试 : Jest + babel
· 真实浏览器测试(不推荐)
· E2E 测试 : Jest + Puppeteer
稍作总结
上面的内容介绍了 chai ,mocha , karma , jasmine 和 jest, 每种工具分别对应一些自己特有的工具链,在选取合适的测试工具时根据实际需要选择, 测试领域还有非常多的工具数都数不过来,下面来看下 React 单元测试的一些方法。
使用 Jest + Enzyme 对 React 进行单元测试
Enzyme基础配置如下:
npm install enzyme enzyme-adapter-react-16 jest-enzyme jest-environment-enzyme jest-canvas-mock react@16 react-dom@16 --save-dev
// jest.config.js
{
- "testEnvironment": "jsdom",
+setupFilesAfterEnv: ["jest-enzyme", "jest-canvas-mock"],
+testEnvironment: "enzyme",
+testEnvironmentOptions: {
+ "enzymeAdapter": "react16"
+},
}jest-canvas-mock 这个包是为了解决一些使用 JSDOM 未实现行为触发警告的问题。
上面建立了一个使用 Enzyme 比较友好的环境,可以直接在全局作用域里引用 React , shallow, mount 等 API。此外 Enzyme 还注册了许多友好的断言函数到 Jest 中,如下所示:
toBeChecked()
toBeDisabled()
toBeEmptyRender()
toExist()
toContainMatchingElement()
toContainMatchingElements()
toContainExactlyOneMatchingElement()
toContainReact()
toHaveClassName()
toHaveDisplayName()
toHaveHTML()
toHaveProp()
toHaveRef()
toHaveState()
toHaveStyle()
toHaveTagName()
toHaveText()
toIncludeText()
toHaveValue()
toMatchElement()
toMatchSelector()// js/ClassComponent.js
import React from 'react';
export default class ClassComponent extends React.PureComponent {
constructor() {
super();
this.state = { name: 'classcomponent' };
}
render() {
return (
<div>
a simple class component
<CustomComponent />
</div>
);
}
}
// test/hook.test.js
import HookComponent from '../js/HookComponent';
describe('HookComponent', () => {
it ('test with shallow', () => {
const wrapper = shallow(<HookComponent id={1} />);
expect(wrapper).toHaveState('name', 'classcomponent');
expect(wrapper).toIncludeText('a simple class component');
expect(wrapper).toContainReact(<div>a simple class component</div>);
expect(wrapper).toContainMatchingElement('CustomComponent');
})
})Enzyme 提供了三种渲染组件方法:
· shallow 使用 react-test-renderer 将组件渲染成内存中的对象, 可以方便进行 props, state 等数据方面的测试,对应的操作对象为 ShallowWrapper,在这种模式下仅能感知到第一层自定义子组件,对于自定义子组件内部结构则无法感知。
· mount 使用 react-dom 渲染组件,会创建真实 DOM 节点,比 shallow 相比增加了可以使用原生 API 操作 DOM 的能力,对应的操作对象为 ReactWrapper ,这种模式下感知到的是一个完整的 DOM 树。
· render 使用 react-dom-server 渲染成 html 字符串,基于这份静态文档进行操作,对应的操作对象为 CheerioWrapper。
页:
[1]