jasmine
简介
jasmine 是一个测试驱动开发(TDD)测试框架, 一个js测试框架,它不依赖于浏览器、dom或其他js框架
jasmine有十分简洁的语法
使用
从 下载 stantd-alone安装包,并解压,双击打开里面的 specRunner.html
, 即可看到测试示例,我们只要将自己的js源文件和测试文件分别放到 src
和 spec
文件夹中。
specRunner.html
到底是长什么样子的呢? f12
我们发现 先后加载了 jasmine.css, jasmine.js ,jasmine-html.js, boot.js
jasmine框架相关文件和 我们的 js源文件
jasmine测试文件
语法
分组 describe()
describe的作用是群组相关的测试, describe是可以嵌套的 从外到内 walkdown describe层级的 beforeEach
, 由内到外walkup describe层级的 afterEach
describe('a suite', function(){ //这是一个测试分组 it('with an expactation',function(){ expect(true).toBe(true); });});
测试it()
describe
和 it
都是函数,所以它们可以包含任何js代码, 在 describe
中声明的变量和方法,能在 it
中被访问。
it
代表的是具体的测试,当其中所有的断言都为true时,则该测试通过; 否则测试失败
describe('a suit is just a function', function(){ var a = 10; it('and here is a test', function(){ var a = true; expect(a).toBe(true); });});
期望expect()
desribe('the "toBe" matcher compares with "===" ', function(){ it('positive expect', function(){ expect(true).toBe(true); }); it('negative expect', function(){ expect(false).not.toBe(true); });});
匹配 to*() #### 每个匹配方法在期望值和实际值之间执行逻辑比较,它负责告诉jasmine断言的真假,从而决定测试的成功或失败。
肯定断言 expect(true).toBe(true);
否定断言 expect(false).not.toBe(true);jasmine有很丰富的匹配方法,而且可以自定义匹配方法。 内置的匹配方法有:
- toBe()
- toEqual()
- toMatch()
- toBeUndefined()
- toBeNull()
- toBeTruthy()
- toContain()
- toBeLessThan()
- toBeCloseTo()
toThrowError()
describe("included matchers", function(){ it('"toBe" matcher compares width === ', function(){ var a = 12; var b = a; expect(a).toBe(b); expect(a).not.toBe(null); }); describe('"toEqual" matcher', function(){ it('work for simple literals and variable', function(){ var a = 12; expect(a).toEqual(12); }); it('should work for objects', function(){ var foo = { a: 12, b: 23 }; var bar = { a: 12, b: 23 }; expect(foo).toEqual(bar); //true? }); }); it('"toMatch" matcher is for regular expression', function(){ var message = "foo bar baz"; expect(message).toMatch(/bar/); expect(message).toMatch("bar"); expect(message).not.toMatch(/quue/); }); it('"toBeUndefined" matcher compares against "undefined"', function(){ var a = { foo: "foo" }; expect(a.foo).not.toBeUndefined(); expect(a.bar).toBeUndefined(); }); it(' "toBeNull" matcher compares against "null"', function(){ var a = null; var foo = 'foo'; expect(null).toBeNull(); expect(a).toBeNull(); expect(foo).not.toBeNull(); }); it('"toBeTruthy" matcher is for boolean casting testing' , function(){ var a, foo = 'foo'; expect(foo).toBeTruthy(); expect(a).not.toBeTruthy(); }); it('"toContain" matcher is for finding an item in an array', function(){ var a = ['foo', 'bar', 'baz']; expect(a).toContain('bar'); expect(a).not.toContain('quu'); }); it('"toBeLessThan" matcher is for math comparisons', function(){ var n = 2.23, e = 1.33; expect(e).toBeLessThan(n); expect(n).not.toBeLessThan(e); }); it('"toBeCloseTo" matcher is for precision match comparison', function(){ var n = 1.99, e = 2.35; expect(e).not.toBeCloseTo(n, 2); expect(e).toBeCloseTo(n, 0); }); it('"toThrowError" matcher is for testing a specific thrown exception', function(){ var foo = function(){ throw new TypeError('foo bar baz'); }; expect(foo).toThrowError('foo bar baz'); expect(foo).toThrowError(/bar/); expect(foo).toThrowError(TypeError); expect(foo).toThrowError(TypeError, 'foo bar baz'); }); });
设置和清理 beforeEach(), afterEach()
beforeEach()
在它所属的 describe
块中的每条测试执行前,先执行的js代码, 作用就是设置和初始化一些东西。
afterEach()
和 beforeEach
相反,在 describe
块的每条测试执行后执行, 做一些清理的工作。 describe('tests with "setup" and "tear-down"', function(){ var foo; beforeEach(function(){ foo = 0; foo += 1; //每次测试前都初始化 foo == 1 }); afterEach(function(){ foo = 0; //每次测试完都重置 foo = 0; }); it('it is just a function , so can contain any code', function(){ expect(foo).toEqual(1); }); it('can have more than one expectation', function(){ expect(foo).toEqual(1); expect(true).toEqual(true); });});
this对象
另一种在 beforeEach
afterEach
it
之间共享变量的方法: this对象
, 每次执行完1条测试之后,this
都会被重置为空对象
describe('a suite', function(){ beforeEach(function(){ this.foo = 0; }); it('can use "this" to share initial data', function(){ expect(this.foo).toEqual(0); this.bar = "test pollution?"; }); it('prevents test pollution by having an empty "this" created for next test', function(){ expect(this.foo).toEqual(0); expect(this.bar).toBe(undefined); });});
describe嵌套 beforeEach串行
describe('a suite', function(){ var foo; beforeEach(function(){ foo = 0; foo += 1; }); afterEach(function(){ foo = 0; }); it('a spec', function(){ expect(foo).toEqual(1); }); it('a spec too', function(){ expect(foo).toEqual(1); expect(true).toEqual(true); }); describe('nested inside describe', function(){ var bar; beforeEach(function(){ bar = 1; }); // exec outer's describe beforeEach > this describe's beforeEach it('可以访问外部describe的beforeEach的变量', function(){ expect(foo).toEqual(bar); }); });});
禁用describe或it
xdescribe()
, xit()
和 pending()
xdescribe('a suite',function(){ //will not execute});describe('a suite too', function(){ xit('this test be canceled', function(){ expect(true).toBe(false); }); it('can be desclared with "it" but without a function'); if('can be declared by calling "pending()" in spec body', function(){ expect(true).toBe(false); pending(); //禁用该测试 });});
函数调用监听 spy
spyOn()
, toHaveBeenCalled()
, toHaveBeenCalledWith()
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 all the arguments of its calls', function(){ expect(foo.setBar).toHaveBeenCalledWith(123); expect(foo.setBar).toHaveBeenCalledWith(456, 'another param'); }); it('stops all execution on a function', function(){ expect(bar).toBeNull(); //setBar函数的执行 被spy监听器暂停了。 });});describe('a spy, when configured to call through', function(){ var foo , bar, fetchedBar; beforeEach(function(){ foo = { setBar: function(value){ bar = value; }, getBar: function(){ return bar; } }; spyOn(foo, 'getBar').and.callThrough(); foo.setBar(123); fetchedBar = foo.getBar(); }); it('tracks that the spy was called', function(){ expect(foo.getBar).toHaveBeenCalled(); }); it('should not effect other function', function(){ expect(bar).toEqual(123); }); it('when called returns the requested value' , function(){ expect(fetchedBar).toEqual(123); })});