文章目录
前言
async/await
是node.js回调地狱的终极解决办法,谁用谁知道.
目前基本都采用Babel编译的形式将包含async/await
的代码编译为ES5可执行代码,但是在单元测试中,如果直接使用mocha进行测试,由于测试文件没有被Babel编译,连词法分析也无法通过
引入Babel
以express为例,
npm install --save babel-core
npm install --save babel-preset-stage-3
npm install --save babel-preset-es2015
npm install --save-dev babel-plugin-transform-runtime
npm install --save babel-runtime
在项目根目录中新建.babelrc
文件,输入如下内容:
{
"presets":[
"es2015",
"stage-3"
],
"plugins": [
["transform-runtime", {
"polyfill": false,
"regenerator": true
}]
]
}
在app.js
的加载bodyParser的语句后面添加
require("babel-core/register");
即可通过require的钩子来对之后加载的模块进行自动编译
使用Babel编译测试文件
使用如下语句为mocha进行编译
mocha --compilers js:babel-core/register
将上面的语句写入package.json中的scripts
里的test
与引入Babel一样,如上语句调用了babel-core/register
为转码器,请确保其存在
此处的转码器同样依赖.babelrc
,请再次确认内容是否正确
单元测试
以Think.js(MVC,类似与ThinkPHP)为例,使用如上的配置进行ES6的测试.
首先创建test/index.js
文件,这里调用calculate这个service,测试其中的getResult函数,书写如下内容:
"use strict";
var assert = require("assert");
var path = require("path");
var xlsx = require("xlsx");
var thinkjs = require("thinkjs");
thinkjs.load();
var calculate = think.safeRequire(path.resolve(__dirname, "../src/common/service/calculate.js"));
describe("unit test", function(){
const workbook = xlsx.readFile("/opensource/telecomCharges/testCase.xlsx");
const sheetNames = workbook.SheetNames;
const worksheet = workbook.Sheets[sheetNames[0]];
var json = xlsx.utils.sheet_to_json(worksheet);
var length = json.length;
var outputArr = [];
it("use case "+index, function(done){
let inputData = {
minutes : parseFloat(item["通话分钟"]),
times : parseInt(item["累积未交费次数"]),
isCrossYear : "on",
crossYearPrice: parseFloat(item["跨年未交费金额"]),
};
let instance = new calculate();
let date = instance.getResult(inputData);
outputArr[index]={
"通话分钟":inputData.minutes,
"累积未交费次数":inputData.times,
"跨年未交费金额":inputData.crossYearPrice,
"预期输出":item["预期输出"],
"实际输出":date,
"是否成功":"失败",
};
assert.equal(date.toString(), item["预期输出"]);
outputArr[index]["是否成功"] = "成功";
done();
})
});
上面读取了一个表格文件里的测试用例,并进行自动化单元测试.其中每个it
的测试函数都传入了一个done
参数,这个参数是在异步嵌套最底层中被调用,用来提醒mocha这个测试已经完成了.这里的单元测试没有异步操作,因此可以将done
省略
注意,如果使用了其他框架,请在测试开始时对框架进行初始化.因为使用ES6来继承的话,几乎所有框架都默认会继承运行环境中的某个全局变量,不初始化会导致编译无法通过.以thinkJS为例,使用require("thinkjs").load()来初始化框架环境
var thinkjs = require("thinkjs");
thinkjs.load();
同时,使用如下语句进行require
var calculate = think.safeRequire(path.resolve(__dirname, "../src/common/service/calculate.js"));
think.safeRequire
只是thinkjs对require的一个封装,当对应文件不存在时返回null
好了,现在可以npm test
了,如下,使用边界值,等价类,决策表三种用例设计方法设计出来的102个测试用例全部通过
如果babel-preset-${name}
不存在的话,使用npm install --save-dev babel-preset-${name}
进行安装即可
其他
既然使用了读取表格来进行测试,那么不用表格将输出结果打印出来就十分可惜了.
与很多产品类似,mocha提供一大堆钩子函数,其中describe的钩子函数after(function(){})
能够进行当前describe中所有用例执行完毕后最后要执行的操作.由于node.js异步的特性,mocha的所有用例的测试也会被压入事件循环中的线程池,因此必须使用after
这种钩子函数
after(function() {
var length = json.length;
console.log("writing file")
var _headers = ["用例编号","通话分钟", "累积未交费次数", "跨年未交费金额", "预期输出","实际输出","是否成功"];
var _data = outputArr;
var headers = _headers
.map((v, i) => Object.assign({}, {v: v, position: String.fromCharCode(65+i) + 1 }))
.reduce((prev, next) => Object.assign({}, prev, {[next.position]: {v: next.v}}), {});
var data = _data
.map((v, i) => _headers.map((k, j) => Object.assign({}, { v: v[k], position: String.fromCharCode(65+j) + (i+2) })))
.reduce((prev, next) => prev.concat(next))
.reduce((prev, next) => Object.assign({}, prev, {[next.position]: {v: next.v}}), {});
var output = Object.assign({}, headers, data);
var ref = "A1" + ":" + "G"+length;
var wb = {
SheetNames: ["mySheet"],
Sheets: {
"mySheet": Object.assign({}, output, { "!ref": ref })
}
};
xlsx.writeFile(wb, "/opensource/telecomCharges/output.xlsx");
});
如上就是输出结果数组为表格的代码了.我觉得这里输出部分有些累赘,但是去查询xlsx
这个模块的文档时,并没有找到更加简洁的被抽象为util的内部方法
如下图,这就是输出的表格了,用来演示自动化测试十分方便