QUnit JS单元测试框架.docx

上传人:b****2 文档编号:24108971 上传时间:2023-05-24 格式:DOCX 页数:14 大小:236.53KB
下载 相关 举报
QUnit JS单元测试框架.docx_第1页
第1页 / 共14页
QUnit JS单元测试框架.docx_第2页
第2页 / 共14页
QUnit JS单元测试框架.docx_第3页
第3页 / 共14页
QUnit JS单元测试框架.docx_第4页
第4页 / 共14页
QUnit JS单元测试框架.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

QUnit JS单元测试框架.docx

《QUnit JS单元测试框架.docx》由会员分享,可在线阅读,更多相关《QUnit JS单元测试框架.docx(14页珍藏版)》请在冰豆网上搜索。

QUnit JS单元测试框架.docx

QUnitJS单元测试框架

QUnitJS单元测试框架

目录

为什么要进行JS单元测试2

QUnit简介2

QUnit的优点4

QUnit的缺点4

QUnit使用方法4

Setup5

Assertions6

AsynchronousCallBack11

SynchronousCallBack12

与浏览器自动化测试工具集成的接口13

为什么要进行JS单元测试

要自动测试应用程序和框架,甚至受益于测试驱动设计。

这需要编写一系列的测试代码,它涉及到了很多内容以涵盖所有的细节,并需要在各种浏览器测试js代码的特殊性。

由于存在浏览器解析环境、用户操作习惯等等差异,前端程序的许多问题是无法捕捉或重现,现在前端程序的测试多是黑盒测试,即靠点击、点击、再点击来寻找程序bug。

这种方式既费时费力,又无法保证测试的覆盖面。

同时,前端逻辑和交互越来越复杂,和其他编程语言一样,一个函数,一个模块,在修改bug或添加新功能的过程中,很容易就产生新的bug,或使老的bug复活。

这种情况下,反复进行黑盒测试,其工作量和测试质量是可想而知的。

此外,浏览器兼容性测试是前端程序测试的重要一环,在多个浏览器之间测试前端程序,上面说的工作量就会成集合倍的增加。

Js单元测试组件也比较多,由于公司决定采用JQuery作为Web开发的核心框架,且QUnit属于jQuery的单元测试的原生组件,显然更符合我们的要求,这里也只针对Qunit进行介绍。

QUnit简介

QUnit是一个功能强大,易于使用的JavaScript单元测试组件。

它使用了jQuery、jQueryUI和jQuery移动项目来测试任何普通的JavaScript代码,也包括其自身。

QUnit最初是由JohnResig作为jQuery的一部分而开发的,在2008年才进行独立,并提供了API文档,允许其他人使用Qunit进行自己项目的单元测试。

当时它仍然依赖jQuery。

在2009年重写时取消了依赖的耦合,现在QUnit完全可独立运行。

使用QUnit,你只需要在你的HTML页面包括两QUnit文件:

●qunit.js:

测试运行和测试框架;

●qunit.css:

风格测试套件的页面来显示测试结果:

最简单的样例:

DOCTYPEhtml>

QUnit最基本的测试

●当所有测试均已都通过,测试组件的标题显示页标题、绿色的条(当失败时会显示红色条)、navigator.userAgent字符串(显示内容为不同的浏览器中测试结果),带有灰色栏和带有几个复选框来筛选测试结果的栏。

●当大量的测试运行,且仅有少数失败时,"隐藏通过测试"很有用。

该选项将会隐藏通过的测试,易于检查失败的测试。

●该页面的实际内容是测试的结果。

在测试的名称编号的列表开头的每个条目之后,在括号内,数量的失败、传递、和总的断言。

单击该条目将显示每个断言,通常是预期与实际的对比结果显示。

点击运行该则重新测试。

QUnit的优点

●使用起来非常方便,有漂亮的外观和完整的测试功能(包括异步测试),这是见过最漂亮最详细的测试界面了。

●非常简单,容易上手,目前公开的APi只有16个。

●不需要依赖其它任何软件包或框架,只要能运行JS的地方就可以,QUnit本身只有一个JS文件和CSS文件,当然如果需要可以和JQuery等其它框架集成。

●不仅支持在浏览器中测试,还支持在Rhino和node.js等后端测试。

QUnit的缺点

对自动化支持不好,很难和Ant/Maven或自动构建等工具集成,主要用在浏览器中进行测试。

QUnit使用方法

QUnit的用法比较简单,API不是很多,所有的API也就16个左右。

所有的API可以分为三类:

Setup,Assertions,AsynchronousTesting,下面就分别对这些API做些介绍,约定:

凡是用[]包起来的参数表示可选参数。

Setup

test(name,[expected],test)

代表QUnit中的一个测试,就是没添加一个测试就调用一次test(),name参数是要测试的名称,比如”加法函数”或”add”等,expected参数是可选参数,用来表示该测试函数的断言的数量,是个正整数,test参数是一个函数对象,所有的测试代码都应该包括在该函数里,通常这是一个匿名函数。

例如:

test(“addfunction”,1,function(){equal(add(1,2),3);});

asyncTest(name,[expected],test)

代表QUnit中的一个异步测试,这个会在异步测试中,参数同上一个test(name,expected,test)

expect(amount)

用在测试函数中,用于声明测试断言的数量,这个函数和test(name,expected,test)的expected参数的作用是一样的,两个用一个即可,当然都不用也没有关系。

主要作用就是检查你声明的个数和你写的断言的实际个数是否一致。

module(name,[lifecycle])

这个函数主要用于测试函数的分组,你可以理解一个module函数是一个模块的意思,比如module(“validate”)表示后面的测试用例都是alidate相关的代码,或者module(“common.js”),表明后面的测试用例都是common.js里面的代码,如何划分看个人理解啦,一个测试文件是可以写多个module的。

name参数是分组或者模块的名称,lifecycle是可选参数,它是一个对象类型,可以设置setup和teardown回调函数,例如module(“common.js”,{setup:

function(){},teardown:

function(){}}),setup回调函数将会在module开始之前执行,比如可以为该module下面的测试代码做一些准备工作,teardown回调函数将会在该module的所有测试代码执行后执行,比如做一些清理还原工作等。

module("core");

test("atestinthecoremodule",function(){

ok(true,"alwaysfine");

});

module("options");

test("atestintheoptionsmodule",function(){

ok(true,"alwaysfine,too");

});

QUnit.init()

用于初始化QUnit测试框架,通常这个函数是不需要我们手工调用的。

QUnit.reset()

重设函数,通常是在每个test函数执行后由QUnit自己调用来重设整个QUnit测试环境,当然必要时我们自己也可以调用它来复原,不过目前我还没有调用过它。

Assertions

所有断言函数的message都是可选参数,可以是一段话来描述整个断言,这样在测试结果页面可以很清楚看出这个断言是干什么的,比如equal(add(1,2),3,“1加2应该等于3″)。

ok(state,[message])

布尔断言,参数state的值为true时表示通过,否则失败。

test("oktest",function(){

  ok(true,"结果为true");

  ok("non-empty","非空字符串"); 

  ok(false,"false测试失败");

  ok(0,"0fails");

  ok(NaN,"NaNfails");

  ok("","emptystringfails");

  ok(null,"nullfails");

  ok(undefined,"undefinedfails");

});

equal(actual,expected,[message])

比较参数actual和expected是否相等,转化为JavaScript代码为if(actual==expected),是不比较类型的。

test("equaltest",function(){

  equal(0,0,"Zero;equalsucceeds");

  equal("",0,"Empty,Zero;equalsucceeds");

  equal("","","Empty,Empty;equalsucceeds");

  equal(0,0,"Zero,Zero;equalsucceeds");

 

  equal("three",3,"Three,3;equalfails");

  equal(null,false,"null,false;equalfails");

});

注:

相比ok()断言,equal()使得更容易调试和测试失败原因,因为是明显值不相等导致失败。

notEqual(actual,expected,[message])

比较两个参数不相等,转化为JavaScript代码为if(actual!

=expected),是不比较类型的,不相等则通过,否则失败。

与equal相反。

deepEqual(actual,expected,[message])

主要用于数组和对象等类型的值是否相等,会递归遍历它们所包含的值是否相等。

此deepEqual()断言就像equal()一样,但相比equal()来说,在大多数情况下,它是一个更好的选择。

它不是简单的比较运算符(==),它会使用更精确的比较运算符(=)。

这样一来,未定义不等于为null,0或空字符串("")。

它也比较对象的内容以便{key:

value}等于{key:

value},甚至能够比较具有两个不同的身份对象。

deepEqual()还处理NaN、日期、正则表达式、数组和函数,而equal()将只检查对象标识:

test("deepEqualtest",function(){

  varobj={foo:

"bar"}; 

  deepEqual(obj,{foo:

"bar"},"Twoobjectscanbethesameinvalue");

});

注:

如果你想明确地比较两个值的内容,仍可使用equal()。

一般情况下,deepEqual()是更好的选择。

same貌似被Qunit废弃了,利用deepEqual代替。

notDeepEqual(actual,expected,[message])

主要用于数组和对象等类型的值是否不相等,会递归遍历它们所包含的值是否不相等,与deepEqual相反。

strictEqual(actual,expected,[message])

比较参数actual和expected的值和类型是否相等,转化为JavaScript代码为if(actual===expected),是需要比较类型的。

test("atest",function(){

varactual=0;

equal(actual,false,"Passes,as0andfalsearethesamewhencomparedwith==");

strictEqual(actual,false,"fails,as0isaNumbertype,falseBoolean");

});

notStrictEqual(actual,expected,[message])

比较参数actual和expected的值和类型是否不相等,转化为JavaScript代码为if(actual!

==expected),是需要比较类型的。

raises(block,expected,[message])

测试block函数是否抛出一个异常,抛出则通过,不抛则失败。

block参数是我们要测试的函数,expected参数是一个函数,是一个可选参数,用来验证第一个函数抛出的异常是否是我们想要的。

test("atest",function(){

functionCustomError(){};

raises(function(){

thrownewCustomError();

},CustomError,"mustthrowerrortopass");

});

AsynchronousCallBack

●异步测试的代码需要写在asyncTest(name,[expected],test)中。

●stop([increment]),停止测试的运行,因为在异步环境中,不停止的话就运行结束了,异步的回调都不会被处理,所以在异步测试时一般先把QUnit的testrunner停下来。

increment参数是增加停止的时间。

●start([decrement]),当异步调用成功后就应该把停止的testrunner启动起来让它接着往前跑了,decrement参数用来减少停止的时间。

●它的用法简单明了,只是在开始测试中调用expect(),预期断言作为唯一的参数:

test("atest",function(){

  expect

(2);

  functioncalc(x,operation){

    returnoperation(x);

  }

  varresult=calc(2,function(x){

    ok(true,"calc()callsoperationfunction");

    returnx*x;

  });

  equal(result,4,"2squareequals4");

});

●或者,也可以作为第二个参数将期望计数传递给test()

test("atest",2,function(){

  functioncalc(x,operation){

    returnoperation(x);

  }

  varresult=calc(2,function(x){

    ok(true,"calc()callsoperationfunction");

    returnx*x;

  });

 equal(result,4,"2squareequals4");

});

SynchronousCallBack

有时,代码中可能会阻止回调断言,永远不会调用,导致测试失败且不显示。

QUnit提供了一个特殊的断言定义,当测试完成时,如果存在不正确的断言,它会失败。

JQuery例子

test("atest",1,function(){

  var$body=$("body"); 

  $body.on("click",function(){

    ok(true,"bodywasclicked!

");

  }); 

  $body.trigger("click");

});

实际测试回调时,expect()提供了最大的价值。

当所有代码运行在测试函数的范围内,expect()提供任何额外的价值——防止断言运行任何能导致测试失败的任何单元。

与浏览器自动化测试工具集成的接口

QUnit额外提供了一些与浏览器自动化测试工具集成的接口,这些接口实现后会被QUnit自动调用,注意,这些接口是留着我们开发人员自己来实现的。

这里简单做些介绍:

●QUnit.log({result,actual,expected,message})

这个接口会在每个断言执行后调用,result值是断言是否通过,message是断言里的message参数。

●QUnit.testStart({name})

在每个测试函数执行前调用,name参数是测试函数中的name参数值,这里的测试函数是指test()或者asyncTest()。

●QUnit.testDone({name,failed,passed,total})

在每个测试函数结束后执行,name参数同上,failed参数是指失败断言的个数,passed参数是指成功断言的个数,total是指所有断言的个数。

●QUnit.moduleStart({name})

在每个module后面所有的测试代码执行前调用,name参数是module(name)中name的值。

●QUnit.moduleDone({name,failed,passed,total}),在module下面所有的测试代码执行完之后执行,failed参数是指失败断言的个数,passed参数是指成功断言的个数,total是指所有断言的个数。

●QUnit.begin()

在所有的测试代码调用之前运行。

●QUnit.done({failed,passed,total,runtime})

在所有的测试代码调用之后运行,failed参数是指失败断言的个数,passed参数是指成功断言的个数,total是指所有断言的个数,runtime代码所有代码的执行时间。

除了学习如何使用QUnit外,QUnit的源代码也是非常不错的学习材料,源代码中除去第三方的代码,也就1000行左右的代码,而且代码写得非常好,建议多阅读它的代码,这样不仅可以学习如何更好些好Javasciprt代码,还可以加深对QUnit的理解。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1