10-Jest&Enzyme执行单元测试
2019-07-09 本文已影响1人
七玄之主
React开发中要进行单测,主要是针对UI层的 React Components 和业务流程的 Redux Saga来进行。
Jest 简介
Jest 是由facebook提供的一个开源 Javascript 测试框架,由于和 React 同出一源,所以能很好的和 React 程序结合使用。
- Jest 是基于Jasmine 2实现的,所以沿用了Jasmine的Matcher,熟悉Jasmine的可以直接上手。
- Jest 执行环境默认是使用的Node.js 上的 jsdom,所以对于 DOM 的操作不依赖浏览器,通过命令行完成,因此不需要安装任何别的测试运行环境。
- 支持 Mock,覆盖率,Snapshots等测试工具。
- 优先执行前回出错的测试,支持并行执行,执行速度很快。
Enzyme 简介
Enzyme 是基于React原生Test Utilities的一个扩展工具包,能够更好的帮助完成React的控件测试。提供了一套类 Jquery查询器语法的选择方法,对于定位Dom元素相当方便。Enzyme 也是 React 官网推荐的进行单测的工具,可以认为是标配了。Test Utilities
开始实现
安装必要包和类型定义文件
yarn add -D jest @types/jest enzyme enzyme-adapter-react-16 @types/enzyme @types/enzyme-adapter-react-16
这里的 enzyme-adapter-react-16 包是为了建立 React 和 enzyme的一个适配器。
接着我们在根目录创建 jest.config.js 的 Jest 配置文件。
module.exports = {
// 设置jsdom运行环境的URL
// 默认值:: http://localhost
testURL: 'http://localhost/',
// glob模式指定查找测试文件的规则
// 默认值:: [ "**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)" ]
testMatch: [
'<rootDir>/**/__tests__/**/*.{js,jsx,ts,tsx}',
'<rootDir>/**/*.{spec,test}.{js,jsx,ts,tsx}',
],
// 项目模块中使用的文件扩展名数组
// 默认值:: ["js", "json", "jsx", "ts", "tsx", "node"]
// 因为是从左到右寻找,推荐将自项目常用的文件扩展名排在前面
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
// 每个测试文件运行前执行指定代码配置或者是创建测试环境
// 默认值:[]
setupFiles: [
'<rootDir>/__test__/test.setup.ts',
],
// 指定测试环境
// 默认值︰"jsdom",这里是指jsdom11
// 可以安装自定义的测试环境,来指定对应的jsdom版本,例如jest-environment-jsdom-fourteen
testEnvironment: 'jsdom',
// 指定模块的搜索路径
// 默认值:[]
modulePaths: ['<rootDir>/src/'],
// 允许使用一个简单的module,来替换类似图片,样式类的资源
// 默认值︰null
moduleNameMapper: {}
};
Jest 的配置相当丰富,你可以通过一个简单的配置扩展自己的实际项目需求,具体配置请参照官方文档 Configuring Jest
完成配置后,在根目录新建如下项目结构
__test__
├─ components/
└─ sagas/
test.setup.ts
如上面配置所示,test.setup.ts完成了再运行测试之前,对于 Enzyme 的配置启动。
test.setup.ts
/* eslint-disable import/no-unresolved */
import Enzyme from "enzyme";
import Adapter from "enzyme-adapter-react-16";
Enzyme.configure({ adapter: new Adapter() });
我们分别针对组件 Header 和 novel的saga业务流程增加单元测试。
Header.spec.tsx
/* eslint-disable import/no-unresolved */
import React from "react";
import { shallow } from "enzyme";
import Header from "../../src/components/Header";
describe("<Header />", () => {
it("renders four li tag", () => {
const wrapper = shallow(<Header />);
expect(wrapper.find("ul Link")).toHaveLength(4);
});
});
novel.spec.ts
import { watchSearchNovels } from "../../src/sagas/novel";
import { take, call } from "redux-saga/effects";
import { fetchNovels } from "../../src/actions/novel";
import { queryNovels } from "../../src/services/novelapi";
test("watchSearchNovels Saga test", () => {
const gen = watchSearchNovels();
expect(gen.next().value).toEqual(take(fetchNovels));
expect(gen.next().value).toEqual(call(queryNovels));
});
以上演示的只是简单应用,对于复杂的测试可能需要增加Mock操作或者引入其他工具插件,后续会陆续记录追加。
最后我们修改package.json,增加对应的执行命令。
"scripts": {
"build": "webpack --config webpack.prod.js",
"build_dev": "webpack --config webpack.dev.js",
"dev": "webpack-dev-server --open --config webpack.dev.js",
"mock": "node ./src/mock/mock-server.js",
"test": "jest",
"test_dev": "jest --coverage"
},
执行yarn test
如此我们可以愉快的开始写单体测试代码了。