jasmine是基于BDD模式的测试框架,详细介绍请上网查看,在此我们直接进入实战。
本文以jasmine1.3为例,因为最新版的Karma v0.12.9 使用的为jasmine1.3。
参考文档:http://jasmine.github.io/1.3/introduction.html
jasmine测试用例的书写格式:
describe("用户登录功能", function() { it("密码验证", function() { expect(true).toBe(true); }); it("重复密码", function() { expect(true).toBe(true); }); it("登录事件", function() { expect(true).toBe(true); }); it("登录界面", function() { expect(true).toBe(true); }); }); //测试套件的嵌套 describe("用户管理", function() { describe("用户登录功能", function() { it("密码验证", function() { expect(true).toBe(true); }); it("重复密码", function() { expect(true).toBe(true); }); it("登录事件", function() { expect(true).toBe(true); }); it("登录界面", function() { expect(true).toBe(true); }); }); });
可用的匹配器:
expect(true).toBe(true); expect(false).not.toBe(true); expect(a).toEqual(12); expect(message).toMatch(/bar/); expect(message).toMatch('bar'); expect(message).not.toMatch(/quux/); expect(a.foo).toBeDefined(); expect(a.bar).not.toBeDefined(); expect(a.foo).not.toBeUndefined(); expect(a.bar).toBeUndefined(); expect(null).toBeNull(); expect(a).toBeNull(); expect(foo).not.toBeNull(); expect(foo).toBeTruthy(); expect(a).not.toBeTruthy(); expect(a).toBeFalsy(); expect(foo).not.toBeFalsy(); expect(a).toContain('bar'); expect(a).not.toContain('quux'); expect(e).toBeLessThan(pi); expect(pi).not.toBeLessThan(e); expect(pi).toBeGreaterThan(e); expect(e).not.toBeGreaterThan(pi); expect(pi).not.toBeCloseTo(e, 2); expect(pi).toBeCloseTo(e, 0); expect(foo).not.toThrow(); expect(bar).toThrow();
测试用例的前置和后置函数
http://powertech.iteye.com/blog/2065922
beforeEach afterEach
describe("用户登录功能", function() { beforeEach(function(){ console.log('前置函数,下面的每个测试用例之前执行一次'); }); afterEach(function(){ console.log('前置函数,下面的每个测试用例之后执行一次'); }); it("密码验证", function() { expect(true).toBe(true); }); it("重复密码", function() { expect(true).toBe(true); }); it("登录事件", function() { expect(true).toBe(true); }); it("登录界面", function() { expect(true).toBe(true); }); });
探测器:探测函数的执行过程,以及动态修改
函数的参数和返回值。
http://powertech.iteye.com/blog/2065922
describe("A spy", function() { var foo, bar = null; beforeEach(function() { foo = { setBar: function(value) { bar = value; } }; spyOn(foo, 'setBar'); foo.setBar(123); foo.setBar(456, 'another param'); }); it("tracks that the spy was called", function() { expect(foo.setBar).toHaveBeenCalled(); }); it("tracks its number of calls", function() { expect(foo.setBar.calls.length).toEqual(2); }); it("tracks all the arguments of its calls", function() { expect(foo.setBar).toHaveBeenCalledWith(123); expect(foo.setBar).toHaveBeenCalledWith(456, 'another param'); }); it("allows access to the most recent call", function() { expect(foo.setBar.mostRecentCall.args[0]).toEqual(456); }); it("allows access to other calls", function() { expect(foo.setBar.calls[0].args[0]).toEqual(123); }); it("stops all execution on a function", function() { expect(bar).toBeNull(); }); });
探测器的类型:
http://powertech.iteye.com/blog/2065922
andCallThrough 监听函数的执行过程。
it('andCallThrough',funciton(){ spyOn(myObj,'fun').andCallThrough(); //判断是否返回了期望的结果 var result = myObj.fun(222); expect(result).toBe(234) //可以使用toHaveBeenCalled判断函数是否执行, expect(myObj.fun).toHaveBeenCalled(11); //使用toHaveBeenCalledWith判断是否传入了期望的参数 expect(myObj.fun).toHaveBeenCalledWith(11); });
andReturn:伪造函数的返回值,一般用来在测试用例执行前
为测试用例提前配置好测试环境,减少函数间的依赖。
it('andCallThrough',funciton(){ spyOn(myObj,'getLoginUserID').andReturn(function(para){ //将函数myObj.getLoginUserID的返回值修改为123 return 123; }); var id = myObj.getLoginUserID(para); var user = myObj.getUser(id); } });
andCallFake:伪造函数的调用过程。
it('andCallThrough',funciton(){ spyOn(myObj,'fun').andCallFake(function(para){ //将函数myObj.fun的执行过程改为下面的代码 var i= i+1; return 123; }); myObj.fun1 = function(para){ var ss = myObj.fun(para); return ss*10; } //判断是否返回了期望的结果 var result = myObj.fun(222); expect(result).toBe(1230) });
createSpy:请查看原文档
createSpyObj:请查看原文档
测试用例的同步代码支持:
在测试的时候,有时我们需要某个测试执行时,等待5秒钟之后再开始,
或者满足某个条件后才开始,比如,执行用户管理测试,需要先调用
登录代码后,等待1秒再开始其它测试。
runs(funciton(){ 代码块1 }) runs(funciton(){ 代码块2 })
用于序列化执行的的代码块,多个runs块按顺序执行。
waits(毫秒),执行完此函数,会引起等待,等待结束然后再执行下一个runs代码块或下一个
it测试用例
waitsFor(function(){ //满足条件时返回true if(condition){ return true; } },'失败说明',5000);
waitsFor代码块在5000毫秒内返回true,则执行下一下runs块
如果在5000毫秒内不能返回true,则测试用例失败,不再执行下一个runs代码块。
实例:
describe('等待啊等待',function(){ it('开始,配置环境',funciton(){ //发起一个异步的ajax登录 myusr.login(); //下一个it执行前等待500毫秒, //保证登录已完成。 waits(500); }); it('顺序执行',funciton(){ this.user = myojb.loginUser; runs(function(){ this.user .setName('小花'); }); runs(function(){ this.user .setAge(26); }); waitFor(function(){ if(findFriends(this.user)){ this.friends = findFriends(this.user); return true; } },'条件不具备',5000); runs(function(){ console.log(this.friends); expect(this.friends).toBe('程序员'); }); }); })
和karma的配合
http://powertech.iteye.com/blog/2065922
karma默认每个包含的文件,都是用这种格式包含进一个HTML文档里。
console.log($(document))即可看到:
引用
文件的加载顺序和配置顺序是一样的。
所以可以写一些前置的测试用例,用来初始化测试环境,比如设置登录用户,预加载页面内容
伪造服务器响应,修改服务器地址,设置全局变量,使用waits等待加载等。
当这些测试用测跑完,相当于走了一个初始化过程,再开始其它的测试用例,会省去很多重
复代码。
如:
引用
start config\karma.conf.js
INFO [karma]: Karma v0.12.9 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 34.0.1847 (Windows 7)]: Connected on socket wxF-ypt_qN_FJCIwnwtA with id 65078817
Chrome 34.0.1847 (Windows 7): Executed 0 of 14 SUCCESS (0 secs / 0 secs)
LOG: 'XX测试,初始化...'
Chrome 34.0.1847 (Windows 7): Executed 0 of 14 SUCCESS (0 secs / 0 secs)
Chrome 34.0.1847 (Windows 7): Executed 1 of 14 SUCCESS (0 secs / 0.133 secs)
LOG: '模拟用户登录……'
Chrome 34.0.1847 (Windows 7): Executed 1 of 14 SUCCESS (0 secs / 0.133 secs)
INFO [karma]: Karma v0.12.9 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 34.0.1847 (Windows 7)]: Connected on socket wxF-ypt_qN_FJCIwnwtA with id 65078817
Chrome 34.0.1847 (Windows 7): Executed 0 of 14 SUCCESS (0 secs / 0 secs)
LOG: 'XX测试,初始化...'
Chrome 34.0.1847 (Windows 7): Executed 0 of 14 SUCCESS (0 secs / 0 secs)
Chrome 34.0.1847 (Windows 7): Executed 1 of 14 SUCCESS (0 secs / 0.133 secs)
LOG: '模拟用户登录……'
Chrome 34.0.1847 (Windows 7): Executed 1 of 14 SUCCESS (0 secs / 0.133 secs)
作完这些操作后,其它的测试用例跑起来很方便。
karma里测试文件的加载方式:
http://powertech.iteye.com/blog/2065922
默认情况下,所有文件都使用