javascript单元测试框架Jasmin档案.docx
- 文档编号:23147999
- 上传时间:2023-05-08
- 格式:DOCX
- 页数:19
- 大小:210KB
javascript单元测试框架Jasmin档案.docx
《javascript单元测试框架Jasmin档案.docx》由会员分享,可在线阅读,更多相关《javascript单元测试框架Jasmin档案.docx(19页珍藏版)》请在冰豆网上搜索。
javascript单元测试框架Jasmin档案
Jasmin档案
∙用途:
javascript单元测试框架
∙下载:
∙使用文档:
页面前端逻辑复杂度与日俱增,前端工程师写出来的javascript变得庞大甚至臃肿,维护的难度不断加大,你需要一个javascript单元测试框架,用于降低维护javascript代码时的出错风险,保证重构后的代码的兼容性,最重要的是减少人肉测试的过程,降低js代码维护成本。
jasmine无疑是目前最优秀的javascript单元测试框架之一,在易用性和质量上都非常不错。
在
Jasmineisabehavior-drivendevelopmentframeworkfortestingJavaScriptcode.ItdoesnotdependonanyotherJavaScriptframeworks.ItdoesnotrequireaDOM.Andithasaclean,obvioussyntaxsothatyoucaneasilywritetests.
行为驱动开发(BehaviorDrivenDevelopment)
BDD使用几乎近于自然语言的方式描述了软件的行为过程,因此,可以直接作为软件的需求文档,也可以直接应用到测试中,作为测试的标准文档。
我们在做单元测试时,经常是针对某个函数,或是某个类进行测试,但是被测函数或是被测的类是可能经常变化的,我们的测试案例也需要经常性的随之变化。
然后,BDD描述的是软件的整个系统行为,几近于需求文档,可变性大大减小。
因此,测试案例不需要做太大变化。
同时,这样的测试案例最贴近于需求,贴近于实际的系统行为。
BDD描述的行为就像一个个的故事(Story),系统业务专家、开发者、测试人员一起合作,分析软件的需求,然后将这些需求写成一个个的故事。
开发者负责填充这些故事的内容,测试者负责检验这些故事的结果。
从例子开始
下载[jasmine-standalone-1.2.0.zip](“jasmine-standalone-1.2.0.zip”),解压缩,源文件结构如下:
点击SpecRunner.html,体验一下测试结果界面。
当测试用例的背景全部为绿色时,表示测试通过,红色出现时表示测试失败,代码有问题。
SpecRunner.html是非常标准的单元测试,可以作为你项目测试页面模板。
参考Jasmine提供的demo,编写一个自己的单元测试例子,来阐述Jasmine的用法以及注意点。
以下是代码目录结构:
在spec-runner.html,进行了如下操作:
引入Jasmine提供的CSS和JS文件
通用代码copy到文件中
(function(){
varjasmineEnv=jasmine.getEnv();
jasmineEnv.updateInterval=1000;
varhtmlReporter=newjasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter=function(spec){
returnhtmlReporter.specFilter(spec);
};
varcurrentWindowOnload=window.onload;
window.onload=function(){
if(currentWindowOnload){
currentWindowOnload();
}
execJasmine();
};
functionexecJasmine(){
jasmineEnv.execute();
}
})();
引入需要测试的源文件
引入测试文件
建议源文件和测试文件都body的底部,这样不需要caredomready,可以保持测试文件中代码简单,纯洁。
基本概念
基本概念的描述直接引用jasmine官网首页的表述,在学习和理解基本概念时,请结合以下Testcase代码:
describe('SuperClassTest',function(){
varoSuper;
beforeEach(function(){
oSuper=newSuper('Colin',31);
});
describe('NamerelatedapiTest',function(){
it('shouldgetcorrectnamebygetName',function(){
expect(oSuper.getName()).toEqual('Colin');
});
it('cansetnamebysetName',function(){
oSuper.setName('Peter');
expect(oSuper.name).toEqual('Peter');
});
});
describe('AgerelatedapiTest',function(){
it('shouldgetcorrectagebygetAge',function(){
expect(oSuper.getAge()).toEqual(31);
});
it('cansetagebysetAge',function(){
oSuper.setAge(18);
expect(oSuper.age).toEqual(18);
});
});
});
Suites
describe YourTests.
AtestsuitebeginswithacalltotheglobalJasminefunction describe withtwoparameters:
astringandafunction.Thestringisanameortitleforaspecsuite–usuallywhatisundertest.Thefunctionisablockofcodethatimplementsthesuite.
Specs
SpecsaredefinedbycallingtheglobalJasminefunction it,which,like describe takesastringandafunction.Thestringisatitleforthisspecandthefunctionisthespec,ortest.Aspeccontainsoneormoreexpectationsthattestthestateofthecodeundertest.
AnexpectationinJasmineisanassertionthatcanbeeithertrueorfalse.Aspecwithalltrueexpectationsisapassingspec.Aspecwithoneormoreexpectationsthatevaluatetofalseisafailingspec.
Expectations
Expectationsarebuiltwiththefunction expect whichtakesavalue,calledtheactual.ItischainedwithaMatcherfunction,whichtakestheexpectedvalue.
Matchers
Eachmatcherimplementsabooleancomparisonbetweentheactualvalueandtheexpectedvalue.ItisresponsibleforreportingtoJasmineiftheexpectationistrueorfalse.Jasminewillthenpassorfailthespec.
Anymatchercanevaluatetoanegativeassertionbychainingthecallto expect witha not beforecallingthematcher.
结合上面代码和概念描述,可以得出自己的理解:
∙一个describe相当于一个testsuite(测试套件)
∙describe里可以嵌套describe
∙一个it相当于是一个testcase(测试用例),一个describe里可以有多个it
∙expect相当于是assert(断言)
测试用例中代码执行顺序
describe和it方法调用时传入的第二个参数的执行循序是怎么样的?
更改dom.spec.js成如下代码:
describe('DomClassTest',function(){
console.info("dom==>descibe");
it('shouldgetthecorrectdomnodebybyId',function(){
expect(Dom.byId('test')).not.toBeNull();
console.info("dom==>descibe==>it:
byId");
});
it('shouldgetthecorrectdomnodesbybyTag',function(){
vardEms=Dom.byTag('em');
expect(dEms).not.toBeNull();
expect(dEms.length===2).toBeTruthy();
console.info("dom==>descibe==>it:
byTag");
});
});
更改super.spec.js成如下代码:
describe('SuperClassTest',function(){
varoSuper;
beforeEach(function(){
oSuper=newSuper('Colin',31);
});
console.info("super==>descibe:
superclass");
describe('NamerelatedapiTest',function(){
console.info("super==>descibe:
superclass:
namerelatedapi");
it('shouldgetcorrectnamebygetName',function(){
console.info("super==>descibe:
superclass:
namerelatedapi==>it:
getName");
expect(oSuper.getName()).toEqual('Colin');
});
it('cansetnamebysetName',function(){
console.info("super==>descibe:
superclass:
namerelatedapi==>it:
setName");
oSuper.setName('Peter');
expect(oSuper.name).toEqual('Peter');
});
});
describe('AgerelatedapiTest',function(){
console.info("super==>descibe:
superclass:
agerelatedapi");
it('shouldgetcorrectagebygetAge',function(){
console.info("super==>descibe:
superclass:
agerelatedapi==>it:
getAge");
expect(oSuper.getAge()).toEqual(31);
});
it('cansetagebysetAge',function(){
console.info("super==>descibe:
superclass:
agerelatedapi==>it:
setAge");
oSuper.setAge(18);
expect(oSuper.age).toEqual(18);
});
});
});
用firefox打开spec-runner.html,可以得到如下结果:
从上面的结果可以看出,先执行所有测试代码的describe中代码块,再执行it中代码块。
在写单元测试的时候,原则上,describe之间不要相互依赖和影响,it之间不要相互依赖和影响,否则会影响测试结果。
BeforeandAfter
beforeEach和afterEach
更改super.spec.js成如下代码:
describe('SuperClassTest',function(){
varoSuper;
beforeEach(function(){
oSuper=newSuper('Colin',31);
console.info("beforeEachisrun");
});
afterEach(function(){
console.info("afterEachisrun");
});
describe('NamerelatedapiTest',function(){
it('shouldgetcorrectnamebygetName',function(){
expect(oSuper.getName()).toEqual('Colin');
console.info("ThetestcaseforgetNameisrun");
});
it('cansetnamebysetName',function(){
oSuper.setName('Peter');
expect(oSuper.name).toEqual('Peter');
console.info("ThetestcaseforsetNameisrun");
});
});
describe('AgerelatedapiTest',function(){
it('shouldgetcorrectagebygetAge',function(){
expect(oSuper.getAge()).toEqual(31);
console.info("ThetestcaseforgetAgeisrun");
});
it('cansetagebysetAge',function(){
oSuper.setAge(18);
expect(oSuper.age).toEqual(18);
console.info("ThetestcaseforsetAgeisrun");
});
});
});
用firefox打开spec-runner.html,可以得到如下结果:
为了保证it里执行的代码不相互影响,保证测试的准确性,需要对测试的对象,进行初始化,但如果把这个代码放在每个it里面去执行,这个是一个比较痛苦的事情。
但把初始化代码放到beforeEach里,就可以很好的做到测试代码的简化,因为在每个it执行前,要先执行beforeEach。
同理,可以把一些destory,clean等相关代码放到afterEach里。
after
更改super.spec.js成如下代码:
describe('SuperClassTest',function(){
varoSuper;
beforeEach(function(){
oSuper=newSuper('Colin',31);
});
describe('NamerelatedapiTest',function(){
it('shouldgetcorrectnamebygetName',function(){
console.info("beforethespecruning");
this.after(function(){
console.info('Itisrunafterthespechasfinishedrunning');
});
expect(oSuper.getName()).toEqual('Colin');
console.info("afterthespecruning");
});
it('cansetnamebysetName',function(){
oSuper.setName('Peter');
expect(oSuper.name).toEqual('Peter');
});
});
describe('AgerelatedapiTest',function(){
it('shouldgetcorrectagebygetAge',function(){
expect(oSuper.getAge()).toEqual(31);
});
it('cansetagebysetAge',function(){
oSuper.setAge(18);
expect(oSuper.age).toEqual(18);
});
});
});
用firefox打开spec-runner.html,可以得到如下结果:
无论spec里的测试是否通过,after里传入的回调方法都会执行。
CustomizeMatchers
jasmine自带的matcher已经可以满足常用的测试需求。
自带的matcher如下图所示:
提示:
TheoldmatcherstoNotEqual,toNotBe,toNotMatch,andtoNotContainhavebeendeprecatedandwillberemovedinafuturerelease.Pleasechangeyourspecstousenot.toEqual,not.toBe,not.toMatch,andnot.toContainrespectively.
Everymatcher’scriteriacanbeinvertedbyprepending.not:
expect(x).not.toEqual(y);comparesobjectsorprimitivesxandyandpassesiftheyarenotequivalent。
jasmine也提供了用户自定义Matchers的功能,而且提供了标准的写法,看下面一个例子,下面例子提供了1个自定义的matchers,判断dom元素是否有某个cssclass.
beforeEach(function(){
this.addMatchers({
toContainClass:
function(expected){
varactual=this.actual;
this.message=function(){
return"Expected"+actual+"doesn'tcontaincss"+expected;
}
returnactual.className.indexOf(expected);
}
});
});
Spies
spy可以用来监视函数的运行情况,观察类构造函数或者方法的调用情况,还可以伪造行为。
spy会替换掉被监视的函数。
具体请参考相关jasminespies相关文档。
静态方法、实例的方法、回调函数
增加kclass.js和kclass.spec.js,并在spec-runner.html中引用。
源代码:
varKlass=function(){
};
Klass.staticMethod=function(arg){
returnarg;
};
Klass.prototype.method=function(arg){
returnarg;
};
Klass.prototype.methodWithCallback=function(callback){
returncallback('foo');
};
测试代码:
describe('spybehavi
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- javascript 单元测试 框架 Jasmin 档案