测试环境搭建(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了。

results matching ""

    No results matching ""