日期:2014-05-16 浏览次数:20322 次
? 前些天在项目中由于要用到单元测试,包装了一个基于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