js简单放羊式单元测试-上
这是看了很多js单元测试资料后第一次自己做单元测试,因为资料都在介绍工具怎么使用,js单元测试的工具是在是太多了,各种风格,各种支持的,新的旧的,so 还是自己动手来体验一次
简单 是我给自己的需求很简单,读取github api 做个简单的列表页面,点击一项跳到详情页面,倾向页面再次读取github api 填充数据
因为以前段时间在看百度GMU 所以就在百度这个基础上做了
其实也是尝试将自己做的东西从各种js框架 ui库中分离出来,
放羊式 是因为我写了 很松散的一些 function 并没有模块化和结构化,模块化和结构化的测试放在第二轮
首先 看一下GMU demo 里的一段代码 我是在demo基础上修改的 对gmu还不是很熟悉
$(function(){ var html = '<ul id="J_widgetList">'; for(var i in widgets){ html += '<li><a href="' + i +'"><img src="./assets/img/' + widgets[i]['icon'] + '" alt="' + widgets[i]['name'] + '">' + '<span class="title">' + widgets[i]['name'] + '</span><span class="desc">' + widgets[i]['description'] + '</span></a></li>'; } html += '</ul>'; $('#scroller1 ul').remove(); $('#scroller1').append(html); // $('.pages').height($('#J_widgetList').height()); setTimeout(function(){ new iScroll('S_widgets'); $(window).trigger('resize'); }, 200); });
读取 api接口 填充重列表页,然后setTimeout 创建iScroll,就可以完成列表页面了
最终效果和图例里面差不多,其实这就是最终效果。。。
这么简单的事情以前我是这么处理的
function yiqian(owner,repo){ $.ajax({ url: 'https://api.github.com/repos/'+owner+'/'+repo+'?callback=?', // post payload: success: function(data){ //1 拼接字符串或着用js模板引擎处理 //2 填充页面dom //3 绑定list的事件 // cbfn(data) } }) }
但是现在要做单元测试,
1 我要测试 接口返回的内容是不是我想要的
原因:无数次上线表明本地、测试站、正式站存在配置错误而谁都不知道,尤其是新老接口等等,不测就是坑
2 我要测试纯js处理数据结果是不是我想要的
原因:无数次上线表明处理结果 a 处理结果b 处理结果c可能 要同时上线进行运营验证那个效果好,不测试就是坑
3我要测试绑定事件知否正常
原因:无数次上线表明:哎呀,昨天还可以点击的今天怎么没了,本地、测试都好好的呢。。。。。
我选择资料最简单 用户群最多的qunit 做单元测试工具
没有看过 qunitjs cookbook 的清看这里 http://qunitjs.com/cookbook/
有言在先:qunitjs 的同步回调和异步回调和我把同步异步回调搞在一起具体怎么弄我还不是很清楚 ,so我这次是按照异步回调处理的,如果错了请大家改正
异步回调怎么做单元测试 http://qunitjs.com/cookbook/#asynchronous-callbacks
asyncTest( "asynchronous test: one second later!", function() { expect( 1 ); setTimeout(function() { ok( true, "Passed and ready to resume!" ); start(); }, 1000); });1
哎 我发现了,需要吧测试代码写到异步回调回调的方法里面去,这样刚才那个ajajx就得改改了
function yiqian(owner,repo,cbfn){ $.ajax({ url: 'https://api.github.com/repos/'+owner+'/'+repo+'?callback=?', // post payload: success: function(data){ //1 拼接字符串或着用js模板引擎处理 //2 填充页面dom //3 绑定list的事件 cbfn(data) } }) }
给最后加一个处理数据的回调方法
单元测试代码很简单
asyncTest( "asynchronous test: ajax data ready1 ", function() { expect( 1 ); var $video = $( "video" ); getgithubrepositories(function(data){ var flag=false; if(data.data.length>0) { flag=true; } ok( flag, "video has loaded and is ready to play2" ); start(); }) });
这是从官网抄袭过来的代码,加了我要测试的东西,注释都没改
这种简单的测试ajax数据的有意义吗?好像意义不大,但
1 我测试了这个接口能不能访问,存不存在,是不是配置正确
2 测试返回数据的版本 是不是我要的,还可以细致的测试数据结构是不是你要的
测试完了数据能不能拿到和数据版本对不对,该测试根据数据生成html片段,这个函数很显然,可以放在刚才的回调函数里面
参数 1 个 就是ajax返回的数据
function makedatatest (data){ var html = '<ul id="J_widgetList">'; var tempfun=$.parseTpl('<li data-owner="<%=owner.login%>" data-repo="<%=name%>" ><a><img src="<%=owner.avatar_url%>" ><span class="title"><%=name%></span><span class="desc"><%=description%></span></a> </li>'); if(data!=null&&data!=undefined&& data.data!=null&&data.data!=undefined){ for(var i=0;i<10;i++) { //html += '<li><a><img src="'+data.data[i].owner.avatar_url+'" ><span class="title">'+data.data[i].name+'</span><span class="desc">'+data.data[i].description+'</span></a> </li>'; html+=tempfun(data.data[i]); } html += '</ul>'; $('#scroller1 ul').remove(); $('#scroller1').append(html); // $('.pages').height($('#J_widgetList').height()); } }
可以看到 这是一个同步的js处理数据的函数,而且是没有回调方法,也是单元测试里面较为简单的,下面是标准的测试代码
test("hello", function() { ok(true, "world"); })
跟着学一遍代码如下
asyncTest("git list dom test", function() { expect( 2 ); var $fixture = $( "#qunit-fixture" ); //#scroller1 var mydom= $fixture.append('<div id="scroller1"></div>') makedata(listdata); var num= $fixture.find('#J_widgetList>li').length; // var num= $('#scroller1>#J_widgetList>li').length; var flag=false; if(num>0) { flag=true } ok(flag, "git list dom2 "); })
注意jq做单元测试,所有和dom相关的修改都要在qunit-fixture 节点下进行,所以就有个准备测试数据的过程,这里先简单这么弄弄
这里通过判断 dom修改后li的数据
1判断 是否执行了拼接
2 判断是否插入的数据到指定位置
3 具体的dom结构的判断 和dom结构版本的判断 这里没做。。。。。先做简单的
下次说说时间绑定和测试