Jasmine是一种JavaScript的测试框架,它不依赖于其他框架,也不依赖于DOM结构。
以下是一些核心概念:
Suites(describe)
Suite表示一个测试集,以函数describe(string, function)封装,它包含2个参数:
string:测试组名称,
function:测试组函数。
一个Suite(describe)包含多个Specs(it),一个Specs(it)包含多个断言(expect)。
describe("This is a suite", function() {
it("This is a specs", function() {
var a = 'abc';
expect(a).toEqual('abc');
});
});
Setup和Teardown操作(beforeEach,afterEach,beforeAll,afterAll)
Jasmine的Setup和Teardown操作(Setup在每个测试用例Spec执行之前做一些初始化操作,Teardown在每个Sepc执行完之后做一些清理操作,这两个函数名称来自于JUnit),是由一组全局beforeEach,afterEach,beforeAll,afterAll函数来实现的。
beforeEach():在describe函数中每个Spec执行之前执行。
afterEach(): 在describe函数中每个Spec数执行之后执行。
beforeAll():在describe函数中所有的Specs执行之前执行,但只执行一次,在Sepc之间并不会被执行。
afterAll(): 在describe函数中所有的Specs执行之后执行,但只执行一次,在Sepc之间并不会被执行。
beforeAll 和 afterAll适用于执行比较耗时或者耗资源的一些共同的初始化和清理工作。而且在使用时还要注意,它们不会在每个Spec之间执行,所以不适用于每次执行前都需要干净环境的Spec。
describe("This is a suite", function() {
beforeEach(function(){
var a = 'abc';
});
afterEach(function(){
a = '';
})
it("This is a specs1", function() {
expect(a).toEqual('abc');
});
});
在每一个specs执行前都会声明变量a为“abc”,而在测试之后,都会将其置为空字符串。
this值
除了在describe函数开始定义变量,用于各it函数共享数据外,还可以通过this关键字来共享数据。
在在每一个Spec的生命周期(beforeEach->it->afterEach)的开始,都将有一个空的this对象(在开始下一个Spec周期时,this会被重置为空对象)。
嵌套Suite
describe函数可以嵌套,每层都可以定义Specs。这样就可以让一个Suite由一组树状的方法组成。
每个嵌套的describe函数,都可以有自己的beforeEach,afterEach函数。
在执行每个内层Spec时,都会按嵌套的由外及内的顺序执行每个beforeEach函数,所以内层Sepc可以访问到外层Sepc中的beforeEach中的数据。类似的,当内层Spec执行完成后,会按由内及外的顺序执行每个afterEach函数。
describe("This is the first describe", function() {
var a;
beforeEach(function() {
a = 'abc';
});
afterEach(function() {
a = '';
});
it("is just a function", function() {
expect(a).toEqual('abc');
});
describe("This is the second describe", function() {
var b;
beforeEach(function() {
b = 'abc';
});
it("is just a function too", function() {
expect(b).toEqual(a);
});
});
});
定义了一个Suites,其中判断变量a是否为“abc”,后嵌套定义一个Suites,判断变量b是否等于变量a。而每一层Suites都含有自己的beforeEach()函数来给变量赋值。
Specs(it)
Specs是测试组里的每个测试体,其中用it()函数定义测试体,传递两个参数:
string:用于描述测试体的名称
function:测试体的主体内容
it("This is a specs", function() {
expect(a).toEqual('abc');
});
多个测试体时
describe("This is a suite", function() {
it("This is a specs1", function() {
var a = 'abc';
expect(a).toEqual('abc');
});
it("This is a specs2", function() {
var b = {};
expect(b).toBe({});
});
it("This is a specs3", function() {
expect(c).toBeUndefined();
});
});
Expectations(expect)
Expectation就是一个断言,以expect语句表示,返回true或fals。expect语句有1个参数,代表要测试的实际值(the actual)。
只有当一个Spec中的所有Expectations全为ture时,这个Spec才通过,否则失败。
Expectation带实际值,它和表示匹配规则的Matcher链接在一起,Matcher带有期望值。
Matchers
Jasmine定义了多个Matchers,用来测试一些变量是否通过。
常见的有:
- toBe():判断两个变量是否全等,类似于“===”;
- toNotBe():与上一个相反,判断两个变量是否不全等,类似于“!==”;
- toBeDefined():检查变量或属性是否已声明且赋值;
- toBeUndefined():与上一个相反;
- toBeNull():判断变量是否为null;
- toBeTruthy():判断变量如果转换为布尔值,是否为true;
- toBeFalsy():与上一个相反;
- toBeLessThan():与数值比较,是否小于;
- toBeGreaterThan():与数值比较,是否大于;
- toEqual():判断变量是否相等,相当于“==”;
- toContain():判断一个数组中是否包含元素(值)。只能用于数组,不能用于对象;
- toBeCloseTo():数值比较时定义精度,先四舍五入后再比较;
it("The 'toBeCloseTo' matcher is for precision math comparison", function() {
var pi = 3.1415926,
e = 2.78;
expect(pi).not.toBeCloseTo(e, 2);
expect(pi).toBeCloseTo(e, 0);
});
- toMatch():按正则表达式匹配;
- toNotMatch():与上一个相反;
- toThrow():检验一个函数是否会抛出一个错误。
自定义Matchers的实现
当然,用户可以自定义Matchers。在beforeEach()或it()函数里调用Jasmine.addMatchers(),其中可以传递一个参数expected作为测试值,而实际值则保存在this.actual中,代码如下:
describe("This is a suite", function() {
beforeEach(function(){
var a = 'abc';
this.addMatchers({
toBeTrue : function(expected){
return this.actual==expected;
}
});
});
it("This is a specs1", function() {
expect(a).toBeTrue('abc');
});
});
代码在beforeEach()中调用this.addMatchers()定义了一个Matchers。定义了ToBeTrue(),传递一个参数expected与实际值作比较。
后面调用该Matchers时,代码expect(a).toBeTrue('abc');中,a则为实际值(this.actual),而“abc”则为参数expected。
该定义的Matchers与原有的toEqual()类似。