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);
})
});