您的位置:首页 > 其它

Jasmine文档(一)

2016-08-04 18:44 85 查看

前言

之前看了一些关于Jasmine的文章,后来在官网上看到了文档,试着自己翻译了一下,有问题的欢迎大家指正哈。

官网地址为:Jasmine官方文档

介绍

Jasmine是一种用于测试JavaScript代码的行为驱动开发框架。它不依赖于其他任
4000
何JavaScript框架。它也不需要一个DOM结构。它有一个干净、清晰的语法,所以你可以很轻易地书写单元测试代码。本指南是针对于Jasmine2.4.1版本。

describe("A suite", function() {
it("contains spec with an expectation", function() {
expect(true).toBe(true);
});
});


单独的分配

发布页面有下载独立配置的链接,包括任何用于运行Jasmine的东西。在下载一个特定版本和压缩包之后,打开
SpecRunner.html
启动所包含的specs。你会发现所需要的资源文件和他们各自的specs都在
SpecRunner.html
里的
<head>
标签里引入。

Suites(测试程序组):
describe

Suites直接调用Jasmine的全局函数
describe()
并传递两个参数:
string
function
。字符串表示被测试的Suites的名称或者标题。而函数则是需要实现Suites的代码块。

Specs(测试程序体):
it

Specs通过调用全局函数
it()
来定义,跟describe类似的传递两个参数:
string
function
。字符串是spec的标题,
function
是测试程序或者测试代码。Spec包括一个或多个测试代码的状态期望值(expectations)。Expectations在Jasmine中是一个要么是真要么是假的断言。只有当spec中的断言都为真才可以通过这个测试程序,否则测试返回failing。

It’s Just Functions

既然
describe()
it()
是函数体,它们就可以包含所有可执行的代码去运行单体测试。JavaScript范围规则适用,所以在
describe()
声明的变量在其Suites块内都是可用的。

describe("A suite is just a function", function() {
var a;
it("and so is a spec", function() {
a = true;
expect(a).toBe(true);
});
});


Expectations:
expect

Expectations是函数
expect()
建立的,而expect()函数传递一个称为actual(实际值)的参数。Expectations链式的连接着传递参数expected(期望值)的Matcher函数。

Matchers

每一个Matchers执行实际值(
actual
)和期望值(
expected
)之间的布尔比较。它负责反馈Expectation是否为真给Jasmine,而Jasmine根据这个布尔值比较来决定是否通过这个测试(Suites)。

任何Matcher都能通过在
expect
调用Matcher前加上
not
来实现一个否定的断言(
expect(a).not().toBe(false);
)。

代码如下:

describe("The 'toBe' matcher compares with ===", function() {
it("and has a positive case", function() {
expect(true).toBe(true);
});
it("and can have a negative case", function() {
expect(false).not.toBe(true);
});
});


包含的Matchers

Jasmine有一套功能丰富的Matchers。当一个产品需要调用库里不包括的特殊的断言时,也可以自己定义Matchers。

自定义Matchers

常见的Matchers使用代码如下:

describe("Included matchers:", function() {

it("The 'toBe' matcher compares with ===", function() {
//toBe()类似于"==="
var a = 12;
var b = a;

expect(a).toBe(b);//通过
expect(a).not.toBe(null);//通过,因为a!==null
});

describe("The 'toEqual' matcher", function() {
//toEqual()类似于"=="

it("works for simple literals and variables", function() {
var a = 12;
expect(a).toEqual(12);//通过
});

it("should work for objects", function() {
var foo = {
a: 12,
b: 34
};
var bar = {
a: 12,
b: 34
};
expect(foo).toEqual(bar);//通过,两个对象属性和值都一样
});
});

it("The 'toMatch' matcher is for regular expressions", function() {
//toMatch()用于匹配正则表达式
var message = "foo bar baz";

expect(message).toMatch(/bar/);//通过,参数可以是正则表达式
expect(message).toMatch("bar");//通过,参数可以是字符串
expect(message).not.toMatch(/quux/);//通过,因为toMatch()匹配不到/quux/
});

it("The 'toBeDefined' matcher compares against `undefined`", function() {
//toBeDefined()判断参数是否定义
var a = {
foo: "foo"
};

expect(a.foo).toBeDefined();
expect(a.bar).not.toBeDefined();
});

it("The `toBeUndefined` matcher compares against `undefined`", function() {
//toBeUndefined()判断参数是否为undefined
var a = {
foo: "foo"
};

expect(a.foo).not.toBeUndefined();
expect(a.bar).toBeUndefined();
});

it("The 'toBeNull' matcher compares against null", function() {
//toBeNull()判断参数是否为空
var a = null;
var foo = "foo";

expect(null).toBeNull();
expect(a).toBeNull();
expect(foo).not.toBeNull();
});

it("The 'toBeTruthy' matcher is for boolean casting testing", function() {
//toBeTruthy()判断参数转化为布尔值时是否为true
var a, foo = "foo";

expect(foo).toBeTruthy();//通过,foo变量转变为true
expect(a).not.toBeTruthy();
});

it("The 'toBeFalsy' matcher is for boolean casting testing", function() {
//toBeFalsy()判断参数转化为布尔值时是否为false
var a, foo = "foo";

expect(a).toBeFalsy();
expect(foo).not.toBeFalsy();
});

it("The 'toContain' matcher is for finding an item in an Array", function() {
//toContain()判断元素是否存在于数组内。不适用于对象
var a = ["foo", "bar", "baz"];

expect(a).toContain("bar");
expect(a).not.toContain("quux");
});

it("The 'toBeLessThan' matcher is for mathematical comparisons", function() {
//toBeLessThan()判断实际值是否小于期望值
var pi = 3.1415926,
e = 2.78;

expect(e).toBeLessThan(pi);
expect(pi).not.toBeLessThan(e);
});

it("The 'toBeGreaterThan' matcher is for mathematical comparisons", function() {
//toBeGreaterThan()判断实际值是否大于期望值
var pi = 3.1415926,
e = 2.78;

expect(pi).toBeGreaterThan(e);
expect(e).not.toBeGreaterThan(pi);
});

it("The 'toBeCloseTo' matcher is for precision math comparison", function() {
//toBeCloseTo()数值比较时定义精度,先四舍五入后再比较
var pi = 3.1415926,
e = 2.78;

expect(pi).not.toBeCloseTo(e, 2);
expect(pi).toBeCloseTo(e, 0);
});

it("The 'toThrow' matcher is for testing if a function throws an exception", function() {
//toThrow()判断函数是否会抛出一个错误
var foo = function() {
return 1 + 2;
};
var bar = function() {
return a + 1;
};

expect(foo).not.toThrow();
expect(bar).toThrow();
});

it("The 'toThrowError' matcher is for testing a specific thrown exception", function() {
//toThrowError()判断函数是否抛出一个特别的错误,以下四种都能够通过测试
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");
});
});


使用fail函数手动失败一个Spec

fail()
函数可以使一个spec测试失败,可以传递一个失败信息或者错误对象给函数作为参数。例如:

describe("A spec using the fail function", function() {
var foo = function(x, callBack) {
if (x) {
callBack();
}
};

it("should not call the callBack", function() {
foo(false, function() {
fail("Callback has been called");
});
});
});


返回结果为:



descr
ce04
ibe
集合相关联的测试程序体

describe()
函数将相关了的测试程序体集合起来,参数
string
是为集合起来的程序体所取的名字,并且是连接所有specs给每个spec取一个全称。这个字符串使得能够在一个大型Suite中找到这个spec。例如:

describe("A spec", function() {
it("is just a function, so it can contain any code", function() {
var foo = 0;
foo += 1;

expect(foo).toEqual(1);
});

it("can have more than one expectation", function() {
var foo = 0;
foo += 1;

expect(foo).toEqual(1);
expect(true).toEqual(true);
});
});


代码向我们展示了一个
describe()
函数就是几个spec的集合,并且每个spec里可以包括不止一个断言。

安装与拆卸

为了帮助一个测试体能够DRY(Don’t repeat yourself)任何重复的初始化和销毁代码,Jasmine提供了四个全局函数:
beforeEach()
afterEach()
beforeAll()
afterAll()


顾名思义,
beforeEach()
函数在每一个spec调用时调用,先进行初始化操作,而
afterEach()
则是在每一个spec调用之后调用。例如:

describe("A spec using beforeEach and afterEach", function() {
var foo = 0;

beforeEach(function() {
foo += 1;
});

afterEach(function() {
foo = 0;
});

it("is just a function, so it 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);
});
});


代码中两个spec的代码有一点点不同,在上级作用域(
describe
)定义的参数,在后面都可以对其进行修改赋值。每次spec执行时都初始化
beforeEach()
的内容,之后在下一次继续执行前,调用
afterEach()
将变量重置。

beforeAll()
函数在
describe()
函数运行时,并且在所有spec执行前只调用一次,而
afterAll()
则是在所有spec结束后调用。这两个函数可以用来加速那些需要花费昂贵的初始化和销毁的测试单元。例如:

describe("A spec using beforeAll and afterAll", function() {
var foo;

beforeAll(function() {
foo = 1;
});

afterAll(function() {
foo = 0;
});

it("sets the initial value of foo before specs run", function() {
expect(foo).toEqual(1);
foo += 1;
});

it("does not reset foo between specs", function() {
expect(foo).toEqual(2);
});
});


代码调用
beforeAll()
在所有测试spec开始前对foo赋值为1,在之后的测试改变了foo的值,但不再调用其初始化函数,在下一个spec内,foo等于2,。之后调用
afterAll()
将foo赋值为0。

然而,要小心使用
beforeAll()
afterAll()
函数,毕竟他们在每个spec之间没有进行重置,很容易意外导致在你的测试体之间泄露状态,最终使他们产生错误或无法通过测试。

this
关键字

除了在
describe()
声明变量外,另外一个在
beforeEach()
it()
afterEach()
之间共享变量的方法是使用this关键字。每一个spec的
beforeEach()
it()
afterEach()
拥有相同的在下个spec的
beforeEach()
it()
afterEach()
执行之前会延迟置空的空对象
this
。代码如下:

describe("A spec", function() {
beforeEach(function() {
this.foo = 0;
});

it("can use the `this` to share state", function() {
expect(this.foo).toEqual(0);
this.bar = "test pollution?";
});

it("prevents test pollution by having an empty `this` created for the next spec", function() {
expect(this.foo).toEqual(0);
expect(this.bar).toBe(undefined);
});
});


代码在每个spec之前声明
this.foo
并赋值,在其
it()
函数里能够共享该变量。而在
it()
函数里声明的
this.bar
,在下一个spec执行时无法获得,此时两者的
this
关键字所指向的并不一致。

嵌套describe代码块

describe
可以嵌套调用,而spec可以在任何层次都可以定义。类似于组成一个Suites的树形结构。Spec执行前,Jasmine会按顺序沿着这个树形结构执行每个
beforeEach()
函数。而执行结束后,Jasmine也将沿着树执行
afterEach()
函数。例如:

describe("A spec", function() {
var foo;

beforeEach(function() {
foo = 0;
foo += 1;
});

afterEach(function() {
foo = 0;
});

it("is just a function, so it 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);
});

describe("nested inside a second describe", function() {
var bar;

beforeEach(function() {
bar = 1;
});

it("can reference both scopes as needed", function() {
expect(foo).toEqual(bar);
});
});
});


代码嵌套调用了
describe()
函数,而上一层声明的变量,在下一层Suites仍可以使用。

禁用Suites

通过调用
xdescribe()
函数可以禁用Suites。代码执行时,这些Suites以及里面的任何spec都将跳过,因而他们的结果也不会出现在最终的输出结果中。例如:

xdescribe("A spec", function() {
var foo;

beforeEach(function() {
foo = 0;
foo += 1;
});

it("is just a function, so it can contain any code", function() {
expect(foo).toEqual(1);
});
});


输出结果如图:



挂起Specs

被挂起的spec不会执行。但是他们的名字仍会显示在pending的结果集中。

声明挂起的方式有三种:

1. spec可以使用
xit()
来声明挂起;

2. spec声明时不添加任何函数体也可以在结果中达到挂起的效果;

3. 如果你在spec体内的任何位置调用pending()函数,不管那个断言通过与否,该spec都将被挂起。当Suites结束后,pending所传递的字符串将被作为挂起的理由而显示。

例如:

describe("Pending specs", function() {
xit("can be declared 'xit'", function() {
//使用xit()函数挂起
expect(true).toBe(false);
});

it("can be declared with 'it' but without a function");
//使用空函数体将spec挂起

it("can be declared by calling 'pending' in the spec body", function() {
expect(true).toBe(false);
pending('this is why it is pending');    //调用pending()将其挂起
});
});


最终显示结果为:



有兴趣的同学可以查看下一篇文章:

Jasmine文档(二)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: