测试环境搭建(Mocha + Chai + Sinon)
所用技术介绍
如上所见,我在这里使用Mocha + Chai + Sinon 这几个技术来搭建我们的测试环境,简单介绍如下:
- Mocha:用于运行我们的测试用例。
- Chai:Mocha用的断言库。
Sinon:用于创建一些mocks/stubs/spys。
另外值得一提的是,AirBnB创建了一个专门针对React代码测试的开源程序:Enzyme,有兴趣的可以研究一下。
Mocha安装及环境配置
安装Mocha、Chai以及Sinon
安装很简单,命令如下:
npm i mocha chai sinon --save-dev
因为我们要支持ES6的语法,因此还需要安装一个额外的插件babel-register
:
npm i babel-register --save-dev
写一个简单的测试用例
Mocha默认会去当前目录下找test目录,然后在其中去找后缀为.js的文件。如果需要修改这个目录,可以使用Mocha的参数进行设置。 我们这里创建一个新的目录,叫做test,然后一个新的Spec文件:
index.spec.js
import { expect } from 'chai';
describe('hello react spec', () => {
it('works!', () => {
expect(true).to.be.true;
});
});
这个时候我们在命令行中使用命令mocha --compilers js:babel-register
运行mocha,如果顺利的话,可以看到如下结果:
$ mocha --compilers js:babel-register
hello react spec
√ works!
1 passing (11ms)
简单解释一下这里的babel-register
。如果这里没有添加--compilers
选项,则mocha会按照默认的方式执行,也就是“读取spec文件”->“运行测试用例”。使用了babel-register
之后,则执行顺序为“读取spec文件”->“将ES6代码编译为ES5代码”->“运行测试用例”。
踩坑提醒
如果执行mocha --compilers js:babel-register
命令的时候,出现如下的错误:
$ mocha --compilers js:babel-register
D:\node\webpack-dev-boilerplate\test\index.spec.js:1
(function (exports, require, module, __filename, __dirname) { import { expect } from 'chai';
^^^^^^
SyntaxError: Unexpected reserved word
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:373:25)
at loader (D:\node\webpack-dev-boilerplate\node_modules\babel-register\lib\node.js:126:5)
at Object.require.extensions.(anonymous function) [as .js] (D:\node\webpack-dev-boilerplate\node_modules\babel-register\lib\node.js:136:7)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at C:\Users\i301792\AppData\Roaming\npm\node_modules\mocha\lib\mocha.js:219:27
at Array.forEach (native)
at Mocha.loadFiles (C:\Users\i301792\AppData\Roaming\npm\node_modules\mocha\lib\mocha.js:216:14)
at Mocha.run (C:\Users\i301792\AppData\Roaming\npm\node_modules\mocha\lib\mocha.js:468:10)
at Object. (C:\Users\i301792\AppData\Roaming\npm\node_modules\mocha\bin\_mocha:403:18)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:968:3
这个错误可能是由于Babel的版本引入的。在这里提供了一个解决方案:
在我们项目中创建一个.babelrc文件,其内容如下:
{
"presets": ["react", "es2015"]
}
其作用之前讲过了。现在就可以将我们webpack.config.js
中对应设置删除了:
#webpack.config.js
...
{
test: /\.jsx?$/,
loader: 'babel',
exclude: /node_modules/
},
创建测试工具库test_helper.js
注意到我们在每个测试spec文件中,都会需要引入chai库的expect,这样就会有很多重复代码。当然还有其他一些通用的帮助性代码,因此我们需要一个库来集中进行管理。这里我们创建一个新的文件/test/test_helper.js
:
/test/test_helper.js
import { expect } from 'chai';
import sinon from 'sinon';
global.expect = expect;
global.sinon = sinon;
在这里我只是添加了chai的expect,以及引入了sinon。
现在就可以将index.spec.js
文件的第一行删除,然后通过如下的命令来执行mocha命令了:
mocha --compilers js:babel-register --require ./test/test_helper.js --recursive
执行结果如下:
λ mocha --compilers js:babel-register --require ./test/test_helper.js --recursive
hello react spec
√ works!
1 passing (12ms)
配置package.json
中的快捷方式
在package.json
中我们可以创建上述mocha命令的快捷方式。在scripts
字段中作如下修改:
#package.json
"scripts": {
"test": "mocha --compilers js:babel-register --require ./test/test_helper.js --recursive ./test",
"test:watch": "npm test -- --watch",
"dev": "webpack-dev-server --port 3000 --devtool eval --progress --colors --hot --content-base dist",
"build": "webpack"
},
然后就可以使用
npm run test
来直接运行mocha了。
注意这里我还新增加了一个npm run test:watch
快捷方式,其实就是使用了mocha的--watch
选项。有了它,当我们在对代码进行修改的时候,就会自动运行test了。