日期:2014-05-16 浏览次数:20409 次
? 前些天在项目中由于要用到单元测试,包装了一个基于seajs的Qunit单元测试框架,看了下Qunit的源码,发现Qunit直接支持CommonJs模式的封装:
?
如是,直接移植到seajs下
?
define(function(require, exports, module) {
require('tests/qunit/qunit.css');
//Qunit Code
});
?
? 接下去做基于需求的外层封装:
几个要求,要有直接控制台log功能,有多次注入测试功能:
如下进行封装(assert.js)
?
define(function(require, exports, module) {
var $ = require('lib/jquery');
var q = require('tests/qunit/qunit');
//开启log
var enableLog = function(){
var logs = ["begin", "testStart", "testDone", "log", "moduleStart", "moduleDone", "done"];
for (var i = 0; i < logs.length; i++) {
(function() {
var log = logs[i];
q.QUnit[log] = function() {
console.log(log, arguments);
};
})();
}
};
var _test = function(conf){
var settings = {};
var defaults = {
enableLog : false,
unitTest : $.noop
};
settings = $.extend(true,{}, defaults, conf);
if(settings.enableLog) {
enableLog.call(this);
}
if(settings.unitTest) {
if(!$.isArray(settings.unitTest)){
settings.unitTest = [settings.unitTest];
}
for(var i = 0, len = settings.unitTest.length; i < len; ++i){
settings.unitTest[i].call(this, q);
}
}
};
//一次性run
exports.run = function(conf){
q.QUnit.reset();
_test.call(this, conf);
q.QUnit.load();
};
//开启log
exports.enableLog = enableLog;
//注入前最好reset一下
exports.reset = q.QUnit.reset;
//多次注入testcase
exports.test = _test;
//注入case后要load一下
exports.load = q.QUnit.load;
});
?
?
这样一个经过封装的assert断言module就好了。可以进行log输出进多次的单元测试注入。
?
接下来来一个分发(dispatch)module的单元测试案例:
?
组件的代码:
?
?
define(function(require, exports, module){
var $ = require('lib/jquery');
var _ = require('lib/underscore');
var _url = '/notice/tips4web.json';
var _parameter = {};
var _timer = 60000;
var events = [];
var timeoutFlag = null;
var _fire = function(data){
for(var i=0,l=events.length;i<l;i++){
try{
events[i].fn(data, events[i].arg);
}catch(e){
continue;
}
}
//log(events)
};
exports.update = function(op){
_parameter = op;
};
exports.refresh = function(timer){
_timer = timer || 60000;
if(!!timeoutFlag){
clearInterval(timeoutFlag);
}
var ajaxing = false;
timeoutFlag = setInterval(function(){
if(ajaxing){
return;
}
ajaxing = true;
$.ajax({
global:false,
url : _url,
data : _parameter,
_complete:function(){
ajaxing = false;
},
_success:function(data){
_fire(data);
}
});
}, _timer);
};
exports.subscribe = function(fn,arg){
var id = $.now();
events.push({
id:id,
fn:fn,
arg:arg
});
return id;
};
exports.unsubscribe = function(id){
if(!events || !id){
return false;
}
for(var i=0,l=events.length;i<l;i++){
if(events[i].id === id){
events.splice(i,1);
return true;
}
}
return false;
};
exports.clear = function(){
_parameter = {};
events = [];
};
exports.stop = function(){
if(!!timeoutFlag){
clearInterval(timeoutFlag);
}
};
exports.fire = _fire;
});
?
?
这个组件是一个消息中间件:
?
下面我们测试的要点是测试接口可用性和异步通信的触发及销毁:
?
?
define(function(require, exports, module) {
var assert = require('tests/qunit/assert');
var $ = require('lib/jquery');
var rm = require('module/reminder/reminder-middleware');
var _unitTest = function(q){
var isLogin = true;
var ajaxing;
q.module("reminder 接口测试");
q.asyncTest("没有参数group时", function() {
ajaxing = true;
$.ajax({
global:false,
url:'/notice/tips4web.json',
_comp