使用 JavaScript 写代码的时候,无论是使用 TDD 方法还是为了保证代码的质量和可维护性,都应该考虑加上单元测试。在博文 mocha + chai + Travis CI + Codecov 使用流程 中有简单地介绍了如何使用流行的 JavsScript 库来对代码进行自动测试,检查代码覆盖率。
在那篇文章中,使用的是 Mocha/Chai/istanbul 和在线的 Codecov,以及和 Github 关系密切的 Travis CI,而且测试的 JavaScript 代码是 es5。现在 es2015 已经标准化了,那么教程也需要更新一下了。另外如果项目是私有项目,那么还是使用完备的离线测试环境比较好。接下来就是一个快速可行的教程。
安装和配置
测试框架无需变更,还是 Mocha + Chai 的组合,但是 istanbul 需要稍微变动一下。
如果你不需要 istanbul 做覆盖率测试,那么需要使用
npm install --save-dev babel-register
和mocha --require babel-register
使 mocha 能识别 es2015 的代码
使用新套件,直接安装 npm i -S mocha chai cross-env nyc babel-plugin-istanbul babel-register babel-preset-env
。
mocha 和 chai 不用解释了,nyc
可以理解是 istanbul 的命令行工具;babel-plugin-istanbul
是在 babel 中插入 istanbul,babel-register
是 istanbul 使用的 babel 接口,这样两个库就打通了;最后 babel-preset-env
是 babel 的运行配置。
先来配置 babel-plugin-istanbul
,新建 .babelrc
:
1 | { |
presets
配置告诉 babel 使用 babel-preset-env
。当然也可以用 ‘es2015’ + ‘stage-0’ 的组合,具体可以自行斟酌。
env.test.plugins
告诉 babel 在 NODE_ENV=test
的情况下使用插件 babel-plugin-istanbul
。
接下来配置 babel-register
,新建 .nycrc
:
.nycrc
是 nyc 的配置文件,和.babelrc
类似,当然配置也是可以直接写进package.json
的。
1 | { |
以上的配置直接用了官方的配置。require
字段告诉 nyc 使用 babel-register
,reporter
字段的 ‘lcov’ 会让 nyc 生成 lcov.info
文件和对应的 HTML 报告,如果使用 lcovonly
则只生成 ‘lcov.info’。’text-summary’ 则是会在控制台输出覆盖率等信息。
文件会默认生成在
/coverage
下,可以使用report-dir
字段指定。
最后,在 package.json
中加入:
1 | "scripts": { |
测试编写事例
比如有 index.js
:
1 | export class Test { |
那么可以写 test/index.spec.js
,可以直接上 ES2015 的语法:
1 | import { expect } from 'chai' |
使用 npm test
运行测试,得到:
1 | > cross-env NODE_ENV=test nyc mocha test/**/*.spec.js |
Bonus
在测试中经常需要测试 promise 等异步操作,虽然 Mocha 库是可以使用回调来完成测试的,但是我们当然要用 async/await 啦。
比如,需要测试 index.js
中的 requestAsync
:
1 | export class Test { |
那么需要先 npm i -S babel-polyfill babel-plugin-transform-async-to-generator
。
然后配置 .nycrc
,加上 ‘babel-polyfill’ 支持 generator 运行时:
1 | { |
配置 .babelrc
,加上 ‘transform-async-to-generator’,将 async 模式转换为 generator 模式。
1 | { |
接着这样测试异步:
1 | import { expect } from 'chai' |
在测试项 it
的第二个函数前加 ‘async’ 标志异步,然后在返回 promise 的调用前加上 ‘await’,OK。
1 | > cross-env NODE_ENV=test nyc mocha test/**/*.spec.js |