React单元测试——十八般兵器齐上阵,环境构建篇
一个完整、优秀的项目往往离不开单元测试的环节,就 github 上的主流前端项目而言,基本都有相应的单元测试模块。
就 React 的项目来说,一套完整的单元测试能在在后续迭代更新中回归错误时候给与警示,但鉴于 React 本身的特殊性,我们又常常将其与 webpack 等工具相结合,其单元测试的部署相比常规的项目要折腾的多。
本文将作为 React 单元测试系列的开篇,和大家一同逐步构建其单元测试的环境。
你可以在我的仓库下载到本文的示例。
文件组织和配置
1. 目录结构
我们在项目根目录下新建 src 和 test 文件夹,前者用于存放我们编写的各 React 组件模块,后者则用于存放对应单元测试模块。
接着我们需要一个最本质的 package.json 文件,来描述项目的信息跟依赖模块,在根目录执行
npm init
然后分部输入相关信息(你也可以先一路回车,后续再修改),即可自动生成 package.json。
接着我们先通过 npm 安装 React 所需的两个模块—— react 及 react-dom:
npm install --save-dev react react-dom
这里顺便说一声,React 在 v0.14 开始把 react 模块拆分成了上述的两个包,其中 react 模块 中包含 React.createElement、React.createClass 等API,react-dom 模块中则包含 ReactDOM.render 等API(更具体的可以戳这里了解)。
安装完成后根目录会生成存放各 npm 模块的文件夹 node_modules,我们此刻看到的目录结构是这样的,简简单单:
2. webpack 配置
我们打算随主流以ES6的形式来书写脚本模块,同时新版的 React 也已经把 JSX 的转换权移交给 babel 之类的工具,所以我们打算以 webpack 的形式来配置加载器跟打包。
如果你还不了解 webpack,请移步我的这篇入门文章。
先通过 npm 安装 webpack(后续模块的安装方式不再赘述):
npm install --save-dev webpack
我们要搭建一个极其简单的测试环境,所以暂时只需用到一个很简单的webpack配置,所以咱直接在根目录下新建一个 webpack.config.js:
var webpack = require('webpack'); module.exports = {
entry: undefined,
output: {
pathinfo: true
},
module: {
//加载器配置
loaders: [
{ test: /\.js$/, loader: 'babel-loader' }
]
}
};
注意我们打算对所有 .js 文件配置一个 babel-loader 来转换 JSX 跟 ES6,所以记得通过 npm 安装上 babel-loader。
3. karma 配置
一个好的测试工具能大大提升你的工作效率,而作为Angular团队出品的 karma 是出众的、最受欢迎的一款测试工具,它有如下特点:
1. cli 运行,webstorm下配合完美
2. 良好支持 mocha、jasmine 等测试框架
3. 支持多浏览器的测试
4. 生态好,插件多
5. 集成监控解放双手,文件变化时自动启测,类似gulp的watch功能
要留意的是 karma 的安装最好是以全局的形式来安装,这样才能确保正常使用 karma 的cli功能(我们后续将以 karma XXX 的形式来执行测试):
npm install karma -g
接着我们在根目录下新建 karma.conf.js 配置文件:
var isCI = process.env.CONTINUOUS_INTEGRATION === 'true';
var webpackConfig = require('./webpack.config.js');
module.exports = function(config) {
config.set({ basePath: '', files: [
'test/*.js'
], preprocessors: {
'test/*.js': ['webpack']
}, webpack: webpackConfig, webpackMiddleware: {
noInfo: true
}, port: 9876, colors: true, autoWatch: true, singleRun: isCI
});
};
其中 isCI 变量用于判断当前系统环境是否已默认支持持续集成(通过环境变量CONTINUOUS_INTEGRATION判断,具体CI的变量名或值是什么得依据具体情况来定,譬如 vuejs 中使用的是CI_PULL_REQUEST),若没开启CI则将 singleRun 设为false。
另外我们在 preprocessors 做了定义,要求执行 test 目录下的脚本时先通过 webpack 预处理(转JSX、ES6),并在 webpack 配置项设定其配置为我们之前建立的 webpack.config.js 。
我们打算使用 mocha 来作为单元测试的框架(当然你也可以使用 jasmine),然后使用 phantomjs 来作为测试浏览器引擎。
所以先通过 npm 包安装好这俩个模块的 karma 插件:
npm install --save-dev karma-mocha karma-phantomjs-launcher
然后我们进一步配置 karma.conf.js:
var isCI = process.env.CONTINUOUS_INTEGRATION === 'true';
var webpackConfig = require('./webpack.config.js');
module.exports = function(config) {
config.set({ basePath: '', frameworks: [
'mocha', 'phantomjs'
], files: [
'test/*.js'
], preprocessors: {
'test/*.js': ['webpack']
}, webpack: webpackConfig, webpackMiddleware: {
noInfo: true
}, port: 9876, colors: true, autoWatch: true, browsers: ['PhantomJS', 'PhantomJS_custom'], customLaunchers: { //自定义浏览器启动器
'PhantomJS_custom': {
base: 'PhantomJS',
options: {
windowName: 'my-window',
settings: {
webSecurityEnabled: false
}
},
flags: ['--load-images=true'],
debug: true
}
}, phantomjsLauncher: {
// 资源(比如测试模块)出错时依旧保持phantom不退出
exitOnResourceError: true
}, singleRun: isCI
});
};
到了这一步,我们先假装配置都已经折腾完毕了(其实还没有),下面是新增测试模块
4. 创建测试模块
现在 src 目录下还没有任何 React 组件,我们创建一个 Alert.js:
import React from 'react'; const Alert = React.createClass({
render() {
return (
<div {...this.props}>
{this.props.children}
</div>
);
}
}); export default Alert;
接着在 test 目录下新增一个 Alert.js 文件,用于对上述的 src/Alert.js 组件进行简单的单元测试:
import React from 'react';
import ReactTestUtils from 'react/lib/ReactTestUtils';
import Alert from '../src/Alert'; describe('Alert', () => {
it('往页面插入一段带有strong标签的组件', () => {
let instance = ReactTestUtils.renderIntoDocument(
<Alert>
<strong>Message</strong>
</Alert>
);
assert.ok(ReactTestUtils.findRenderedDOMComponentWithTag(instance, 'strong'));
});
});
如上述代码所示,我们假设往<Alert>组件中放置了一个<strong>标签并渲染到页面上(这里使用了 react/lib/ReactTestUtils 是我们下篇文章要介绍的东西)。
于是我们断言页面上通过此形式所挂载上去的 Alert 组件里肯定有一个 <strong> 标签,如果找不到这个 <strong> 标签则意味着该单元测试失败。
现在我们似乎基本完成了全部的配置,执行 karma 启动单元测试看一看:
karma start --browsers PhantomJS_custom
会发现报错了:
这是 phantomJS 的一个坑导致的—— phantomJS 不支持 Function.prototype.bind ,详情可见此issue。
解决方法也简单,把 karma-phantomjs 替换为 karma-phantomjs-shim 即可。
通过 npm 安装好 karma-phantomjs-shim 后我们修改 karma.conf.js 里的 frameworks 配置项:
frameworks: [
'mocha', 'phantomjs-shim'
],
然后重新执行 karma,会发现继续妥妥地报错:
这是因为 karma 最终是将单元测试运行于一个客户端浏览器中的,而不是node里,而我们的测试模块又没有 require('assert') 的引用,客户端自然取不到assert对象了。
解决方法是使用karma-chai,通过 npm 安装后进一步修改 karma.conf.js 里的 frameworks 配置项,加上 chai 插件:
frameworks: [
'mocha', 'chai', 'phantomjs-shim'
],
然后再执行 karma:
666的~ 到此为止我们的全部配置都折腾完毕。在后续可以使用此方案对 src 目录下的全部组件进行简单的单元测试~ 更多有趣的配置或工具我们在后续的文章再做介绍。
最后依旧提醒一下,本文的示例可以从我的仓库上下载到,有兴趣的读者可以下载了自行研究~ 共勉~
React单元测试——十八般兵器齐上阵,环境构建篇的更多相关文章
- Maven系列第9篇:多环境构建支持,核心开发必备!
maven系列目标:从入门开始开始掌握一个高级开发所需要的maven技能. 这是maven系列第9篇. 整个maven系列的内容前后是有依赖的,如果之前没有接触过maven,建议从第一篇看起,本文尾部 ...
- react 单元测试 (jest+enzyme)
为什么要做单元测试 作为一个前端工程师,我是很想去谢单元测试的,因为每天的需求很多,还要去编写测试代码,感觉时间都不够用了. 不过最近开发了一个比较复杂的项目,让我感觉一旦项目大了.复杂了,而且还是多 ...
- Hyperledger Fabric 1.0 从零开始(三)——环境构建(内网/准离线)
有公网环境的服务器可以直接看 Hyperledger Fabric 1.0 从零开始(二)--环境构建(公网) ,本篇内容与上篇相似,只不过环境搭建需要在内网下,也就是网络被限制的情况下. 1:环境构 ...
- Hyperledger Fabric 1.0 从零开始(二)——环境构建(公网)
1:环境构建 在本文中用到的宿主机环境是Centos ,版本为Centos.x86_647.2,通过Docker 容器来运行Fabric的节点,版本为v1.0.因此,启动Fabric网络中的节点需要先 ...
- SSM框架整合环境构建——基于Spring4和Mybatis3
目录 环境 配置说明 所需jar包 配置db.properties 配置log4j.properties 配置spring.xml 配置mybatis-spring.xml 配置springmvc.x ...
- React 与 Redux 在生产环境中的实践总结
React 与 Redux 在生产环境中的实践总结 前段时间使用 React 与 Redux 重构了我们360netlab 的 开放数据平台.现将其中一些技术实践经验总结如下: Universal 渲 ...
- Cocos2d-x v3.1 GUI系统--环境构建(七)
Cocos2d-x v3.1 GUI系统--环境构建(七) 在使用Cocos2d-x的GUI系统时,由于生成的工程默认是没有将GUI系统所需的库导入到项目的,所以我们必须把库导入到工程中并对工程做一些 ...
- 如何从零搭建一个webpack+react+redux+react-redux的开发环境一入门
阅读本文章的时候,你要有一定的基础知识储备,简单的es6知识,模块化思想知识,js基础知识,node基础知识,react等 首先执行npm init,此时我的文件叫case; 下面安装一些需要的npm ...
- jQuery2.x源码解析(构建篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 笔者阅读了园友艾伦 Aaron的系列博客< ...
随机推荐
- wepack+sass+vue 入门教程(三)
十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...
- C#给PDF文档添加文本和图片页眉
页眉常用于显示文档的附加信息,我们可以在页眉中插入文本或者图形,例如,页码.日期.公司徽标.文档标题.文件名或作者名等等.那么我们如何以编程的方式添加页眉呢?今天,这篇文章向大家分享如何使用了免费组件 ...
- [原] KVM 虚拟化原理探究(1)— overview
KVM 虚拟化原理探究- overview 标签(空格分隔): KVM 写在前面的话 本文不介绍kvm和qemu的基本安装操作,希望读者具有一定的KVM实践经验.同时希望借此系列博客,能够对KVM底层 ...
- Kali对wifi的破解记录
好记性不如烂笔头,记录一下. 我是在淘宝买的拓实N87,Kali可以识别,还行. 操作系统:Kali 开始吧. 查看一下网卡的接口.命令如下 airmon-ng 可以看出接口名称是wlan0mon. ...
- 理解Maven中的SNAPSHOT版本和正式版本
Maven中建立的依赖管理方式基本已成为Java语言依赖管理的事实标准,Maven的替代者Gradle也基本沿用了Maven的依赖管理机制.在Maven依赖管理中,唯一标识一个依赖项是由该依赖项的三个 ...
- AngularJs之九(ending......)
今天继续angularJs,但也是最后一篇关于它的了,基础部分差不多也就这些,后续有机会再写它的提升部分. 今天要写的也是一个基础的选择列表: 一:使用ng-options,数组进行循环. <d ...
- .NET平台开源项目速览(16)C#写PDF文件类库PDF File Writer介绍
1年前,我在文章:这些.NET开源项目你知道吗?.NET平台开源文档与报表处理组件集合(三)中(第9个项目),给大家推荐了一个开源免费的PDF读写组件 PDFSharp,PDFSharp我2年前就看过 ...
- VS2015墙内创建ionic2
开始学习ionic2,试验各种方法,感觉以下是紧跟rc版本的最佳方案 STEP1 设置cnpm npm install -g cnpm --registry=https://registry.npm. ...
- 【一起学OpenFoam】01 OpenFoam的优势
CFD技术发展到今天,已经超过了大半个世纪了,已经涌现出非常多的CFD软件可供人们使用.通用商业CFD软件譬如Fluent.CFX.Star CCM+等在工业上得到了广泛的应用,另外一些专用的软件(如 ...
- 如何开发FineReport的自定义控件?
FineReport作为插件化开发的报表软件,有些特殊需求的功能需要自己开发,开发的插件包帆软官方有提提供,可以去帆软论坛上找,本文将主要介绍如何开发一个自定义控件,这里讲讲方法论. 第一步:实例化一 ...