背景
最近负责一个需求,使用到了jasmine测试框架做单元测试
介绍
Jasmine就是一种JavaScript
单元测试框架,它不依赖任何其他JS框架,也不需要对DOM操作,具有灵巧而明确的语法可以让你轻松的编写测试代码。它是一套Javascript行为驱动开发框架(BDD),干净简洁,表达力强且易于组织,不依赖于其他任何框架和DOM,可运行于Node.js
,浏览器端或移动端。
Jasmine官网
Jasmine github
Jasmine的基础语法
Suites
Suites可以理解为一组测试,使用全局的Jasmin函数describe 创建。describe 函数接受两个参数,一个字符串和一个函数。字符串是这个Suites的名字或标题(通常描述下测试内容),函数是实现Suites的代码块。-
Specs
Specs可以理解为一个测试,使用全局的Jasmin函数it 创建。和describe 一样接受两个参数,一个字符串和一个函数,函数就是要执行的测试,字符串就是测试的名字。一个Spec可以包含多个expectations来测试代码。在Jasmine中,一个expectations就是一个断言,只能是true 或false 。只有全部expectations是true 的时候spec才会通过。由于describe 和it 块实质上都函数,所有他可以包含任何的可执行代码。javascript的作用域规则也是适用的,所以describe 内定义的变量,其内部所有的it 都能访问到。
Expectations
expectations由expect 函数创建。接受一个参数。和Matcher一起联用,设置测试的预期值。
Matchers
在Jasmine中,每个Matcher实现一个“期望值”和“实际值”的布尔判断,Jasmine会根据Mather判断expectation是true 还是false ,然后决定spec是测试通过还是失败。所有Matcher可以通过not 执行否定判断。
-
基础matchers
toBe()
:相当于===比较。toNotBe()
toBeDefined()
:检查变量或属性是否已声明且赋值。toBeUndefined()
toBeNull()
:是否是null。toBeTruthy()
:布尔测试,判断值是否是,或者可以转换为true。toBeFalsy()
toBeLessThan()
:数值比较,小于。toBeGreaterThan()
:数值比较,大于。toEqual()
:相当于==,注意与toBe()的区别。一个新建的Object不是(not to be)另一个新建的Object,但是它们是相等(to equal)的。
expect({}).not().toBe({});
expect({}).toEqual({});
toNotEqual()
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); });
看源码理解用法
getJasmineRequireObj().toBeCloseTo = function () { function toBeCloseTo() { return { compare: function (actual, expected, precision) { if (precision !== 0) { precision = precision || 2; } return { pass: Math.abs(expected - actual) < (Math.pow(10, -precision) / 2) }; } }; } return toBeCloseTo; };
比如第二个expect就是如果pi-e的绝对值小于10的-0次方除以2的值,断言通过
toMatch()
:按正则表达式匹配。toNotMatch()
toThrow()
:检验一个函数是否会抛出一个错误it("toThrow判断一个函数是否有抛出异常", function() { var foo = function() { return 1 + 2; }; var bar = function() { return a + 1; //a不存在 }; expect(foo).not.toThrow(); expect(bar).toThrow(); });
-
其他matchers
jasmine.any(Class)
传入构造函数或者类返回数据类型作为期望值,返回true表示实际值和期望值数据类型相同:it("matches any value", function() { expect({}).toEqual(jasmine.any(Object)); expect(12).toEqual(jasmine.any(Number)); });
jasmine.anything()
如果实际值不是null或者undefined则返回true:it("matches anything", function() { expect(1).toEqual(jasmine.anything()); });
jasmine.objectContaining({key:value})
实际对象只要匹配到有对应的键/值就算匹配通过:foo = { a: 1, b: 2, bar: "baz" }; expect(foo).toEqual(jasmine.objectContaining({bar: "baz"}));
jasmine.arrayContaining([val1,val2,...])
实际数组只要匹配到有包含的数值就算匹配通过:foo = [1, 2, 3, 4]; expect(foo).toEqual(jasmine.arrayContaining([3, 1]));
jasmine.stringContaining(str)
stringContaining可以匹配字符串的一部分也可以匹配对象内的字符串:expect({foo: 'bar'}).toEqual({foo: jasmine.stringMatching(/^bar$/)}); expect('foobarbaz').toEqual({foo: jasmine.stringMatching('bar')});
Setup and Teardown
为了在复杂的测试用例中更加便于组装和拆卸,Jasmine提供了四个函数:
beforeEach(function)
//在每一个测试用例(it)执行之前都执行一遍beforeEach函数; afterEach(function)
//在每一个测试用例(it)执行完成之后都执行一遍afterEach函数; beforeAll(function)
//在所有测试用例执行之前执行一遍beforeAll函数; afterAll(function)
//在所有测试用例执行完成之后执行一遍afterAll函数;
jasmine还有自定义matcher的功能和一些高级功能,暂时没有用到,有机会学习下
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。