什么是Jasmine

Jasmine是一个Javascript的BDD(Behavior-Driven Development)测试框架,不依赖任何其他框架。

如何使用Jasmine

从Github上(https://github.com/pivotal/jasmine/releases)下载所需的Jasmine版本。下载完成之后,直接打开SpecRunner.html即为Demo,除了引入Jasmine框架之外,只需引用自己所需测试的js文件以及Jasmine测试脚本引可。

图1:

基本语法介绍

describe(string, function):可以理解为是一个测试集或者测试包(为了便于称呼,我们本文中统一叫测试集,官方称之为suite),主要功能是用来划分单元测试的,describe是可以嵌套使用的

  • 参数string:描述测试包的信息
  • 参数function:测试集的具体实现

it(string, function):测试用例(官方称之为spec)

  • 参数string:描述测试用例的信息
  • 参数function:测试用例的具体实现

expect:断言表达式

第一个Jasmine例子

Step 1:

我们先创建一个名为myFirstJasmineTest.js的文件。

Step 2:

在Html页面中同时引用jasmine的框架文件与myFirstJasmineTest.js文件,可参考上面的图1。

Step 3:

在myFirstJasmineTest.js文件中添加如下内容:

 describe("My first Jasmine test", function() {
it("a spec with an expectation", function() {
expect(1).toBe(1);
expect(1===1).toBe(true);
expect('a').not.toBe('b');
}); it("an other spec in current suite", function() {
expect(true).toBe(true);
});
}); describe("My first Jasmine test", function() {
it("nothing", function() {
});
});

打开Html页面,Jasmine将自动执行用例:

图2:

从上述例子中我们可以看出:

  • 每个测试文件中可以包含多个describe
  • 每个describe中可以包含多个it
  • 每个it中可以包含多个expect

当然实际上,Jasmine还允许describe的嵌套使用,大家可以自行试试。

expect的使用

首先说一下,所有的expect都可以使用not表示否定的断言。

toBe:基本类型判断

  it("toBe and not.toBe", function() {
expect(1).toBe(1);
expect('a').not.toBe('b');
});

toEqual: toEqual有两种用法,对于基本的类型,toEqual相当于toBe

  it("toEqual and not.toEqual for basic types", function(){
expect(1).toEqual(1);
expect('a').not.toEqual('b');
})

toEqual还可以用来判断对象:

  it("toEqual and not.toEqual for objects", function(){
var o1 = {
name: "Jack",
age: 12
}; var o2 = {
name: "Jack",
age: 12
}; var o3 = {
name: "Tom",
age: 13
}; expect(o1).toEqual(o2);
expect(o1).not.toEqual(o3);
})

toMatch: 使用正则表达式判断

  it("toMatch and not.toMatch", function(){
var str = "Michael Jackson"; expect(str).toMatch(/michael/i);
expect(str).not.toMatch(/tom/i);
})

toBeDefine: 判断是否是undefined

  it("toBeDefined and not.toBeDefined", function(){
var student = {
name: "Jack",
age: 12
}; expect(student.name).toBeDefined();
expect(student.gender).not.toBeDefined();
})

toBeUndefined: 判断是否是undefined,与toBeDefine相反

  it("toBeUndefined and not.toBeUndefined", function(){
var student = {
name: "Jack",
age: 12
}; expect(student.gender).toBeUndefined();
expect(student.name).not.toBeUndefined();
})

toBeNull:判断是否是null

  it("toBeNull and not.toBeNull", function(){
var student = {
name: "Jack",
age: 12,
deskmate: null
}; expect(student.deskmate).toBeNull();
expect(student.name).not.toBeNull();
});

toBeTruthy:判断是否能转换成bool型,判断的是否是True

  it("toBeTruthy and not.toBeTruthy", function(){
var stu1;
var stu2 = "Tom"; expect(true).toBeTruthy();
expect(stu2).toBeTruthy();
expect(stu1).not.toBeTruthy();
expect(undefined).not.toBeTruthy();
});

toBeTruthy:判断是否能转换成bool型,判断的是否是False

  it("toBeFalsy and not.toBeFalsy", function(){
var stu1;
var stu2 = "Tom"; expect(true).not.toBeFalsy();
expect(stu1).toBeFalsy();
expect(stu2).not.toBeFalsy();
expect(undefined).toBeFalsy();
});

toContain: 判断集合是否包含(可以是普通类型,和可以是对象)

  it("toContain and not.toContain", function(){
var arrStr = ["Jack", "Tom", "Mary"];
var arrObj = [{name:"Jack",age:21}, {name:"Tom",age:22}]; expect(arrStr).toContain("Jack");
expect(arrStr).not.toContain("jack"); expect(arrObj).toContain({name:"Jack",age:21});
expect(arrObj).not.toContain({name:"jack",age:21});
});

toBeLessThan: 判断值类型的大小,结果若小则为True(也可以判断字符及字符串,以ascii码的大小为判断依据)

  it("toBeLessThan and not.toBeLessThan", function(){
expect(1).toBeLessThan(1.1);
expect("b").not.toBeLessThan("a");
});

toBeGreaterThan: 判断值类型的大小,结果若大则为True,与toBeLessThan相反(也可以判断字符及字符串,以ascii码的大小为判断依据)

  it("toBeGreaterThan and not.toBeGreaterThan", function(){
expect(1).not.toBeGreaterThan(1.1);
expect("b").toBeGreaterThan("a");
});

toBeCloseTo:判断数字是否相似(第二个参数为小数精度,默认为2位)

  it("toBeCloseTo and not.toBeCloseTo", function(){
var a = 1.1;
var b = 1.5;
var c = 1.455;
var d = 1.459; expect(a).toBeCloseTo(b, 0);
expect(a).not.toBeCloseTo(c, 1);
expect(c).toBeCloseTo(d);
});

toThrow: 判断是否抛出异常

  it("toThrow and not.toThrow", function(){
var foo = function() {
return 1 + 2;
};
var bar = function() {
return a + 1;
}; expect(foo).not.toThrow();
expect(bar).toThrow();
});

toThrowError: 判断是否抛出了指定的错误

  it("toThrowError and not.toThrowError", 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");
});

Setup和Teardown

Jasmine允许在执行测试集/测试用例的开始前/结束后做一些初始化/销毁的操作。

Setup方法:

  • beforeAll:每个suite(即describe)中所有spec(即it)运行之前运行
  • beforeEach:每个spec(即it)运行之前运行

Teardown方法:

  • afterAll:每个suite(即describe)中所有spec(即it)运行之后运行
  • afterEach:每个spec(即it)运行之后运行

示例代码:

 (function(){
var globalCount;
describe("Setup and Teardown suite 1", function() {
var suiteGlobalCount;
var eachTestCount; beforeAll(function() {
globalCount = 0; // 试试注释这行代码,看看对运行结果的影响
suiteGlobalCount = 0;
eachTestCount = 0;
}); afterAll(function() {
//globalCount = 0; // 试试取消这行代码的注释,看看对运行结果的影响
suiteGlobalCount = 0;
}); beforeEach(function() {
globalCount++;
suiteGlobalCount++;
eachTestCount++;
}); afterEach(function() {
eachTestCount = 0;
}); it("Spec 1", function() {
expect(globalCount).toBe(1);
expect(suiteGlobalCount).toBe(1);
expect(eachTestCount).toBe(1);
}); it("Spec 2", function() {
expect(globalCount).toBe(2);
expect(suiteGlobalCount).toBe(2);
expect(eachTestCount).toBe(1);
});
}); describe("Setup and Teardown suite 2", function() {
beforeEach(function() {
globalCount += 2;
}); it("Spec 1", function() {
expect(globalCount).toBe(4);
});
});
})();

示例中的第一个describe,在beforeAll中初始化了各个计数变量,在beforeEach中设置每次执行it后,各个计数变量自增1,在afterAll中,重置了全局性的计数变量(尝试取消afterAll中对globalCount的注释,看看运行结果的变化),在afterEach中,重置了局部计数变量。

第二个describe,在beforeEach中对全局变量globalCount自增2,上述代码中,第一个describe中afterAll中没有对globalCount进行重置,因此执行完第一个describe后,globalCount的值为2,因此第二个describe的globalCount的初始值即为2。

在beforeEach/it/afterEach中,还可以使用this关键字定义变量,需要注意的是,使用this关键字声明的变量,仅在beforeEach/it/afterEach这个过程中传递:

 (function(){
describe("Test 'this'", function() {
beforeEach(function() {
this.testCount = this.testCount || 0;
this.testCount++;
}); afterEach(function() {
//this.testCount = 0; //无论是否有这行,结果是一样的,因为this指定的变量只能在每个spec的beforeEach/it/afterEach过程中传递
}); it("Spec 1", function() {
expect(this.testCount).toBe(1);
}); it("Spec 2", function() {
expect(this.testCount).toBe(1);
});
});
})();

xdescribe/xit的使用

在实际项目中,需要由于发布的版本需要选择测试用例包,xdescribe和xit能很方便的将不包含在版本中的测试用例排除在外。不过xdescribe和xit略有不同:

  • xdescribe:该describe下的所有it将被忽略,Jasmine将直接忽略这些it,因此不会被运行
  • xit:运行到该it时,挂起它不执行
 (function(){
xdescribe("Test xdescribe", function() {
it("Spec 1", function() {
expect(1).toBe(1);
}); it("Spec 2", function() {
expect(2).toBe(2);
});
}); describe("Test xit", function() {
it("Spec 1", function() {
expect(1).toBe(1);
}); xit("Spec 2", function() {
expect(2).toBe(1);
}); xit("Spec 3", function() {
expect(3).toBe(3);
});
});
})();

运行结果:

篇幅和精力原因,关于Jasmine的入门学习,我们将在下一篇中继续。

这里随便扯几句,最近由于新项目开始了,我在项目中同时需要担任PM、BA、开发的角色(哦,对了,我忘了告诉你们,其实我是.net的程序员),确实非常累, 很多东西要学、要做。不过对于技术的热爱(虽然技术不咋滴),我希望不管多忙多累,还是能在技术的道路上继续走下去。大家如果觉得我写的文章还可以,甚至能给你们带来一些小小的收获,希望大家顶一下,给我加加油。 好了,又到凌晨一点半了,我赶紧去睡了,明天还要去客户现场呢。

参考资料

Jasmine: http://jasmine.github.io/

粉丝日志:http://blog.fens.me/nodejs-jasmine-bdd/

Jasmine入门(上)的更多相关文章

  1. Jasmine入门(下)

    上一篇 Jasmine入门(上) 介绍了Jasmine以及一些基本的用法,本篇我们继续研究Jasmine的其他一些特性及其用法(注:本篇中的例子均来自于官方文档). Spy Spy用来追踪函数的调用历 ...

  2. Python入门(上)

    Python入门(上) Python入门(上) 简介 Python 基础语法 行与缩进 注释 运算符 标准数据类型 变量 编程流程 顺序(略) 分支 if 循环 for while break 和 c ...

  3. Jasmine入门(结合示例讲解)

    参考: http://www.cnblogs.com/wushangjue/p/4541209.html http://keenwon.com/1191.html http://jasmine.git ...

  4. MySQL入门(上)

    1 课程回顾 自定义标签&编码实战 1)自定义标签步骤: 1.1 编写标签处理器类,继承SimpleTagSupport类,覆盖doTag方法 1.2 在WEB-INF目录下建立tld文件,在 ...

  5. JVM快速入门(上)

    前言 根据狂神说的JVM快速入门做了以下笔记,讲的很好的一个博主,给小伙伴们附上视频链接狂神说JVM快速入门    接下来我按照他所讲的内容给大家记录一些重点! 一.JVM体系结构 .java经由ja ...

  6. Pytorch入门上 —— Dataset、Tensorboard、Transforms、Dataloader

    本节内容参照小土堆的pytorch入门视频教程.学习时建议多读源码,通过源码中的注释可以快速弄清楚类或函数的作用以及输入输出类型. Dataset 借用Dataset可以快速访问深度学习需要的数据,例 ...

  7. jasmine入门

    本文来自http://blog.fens.me/nodejs-jasmine-bdd 粉丝日志 张丹   前言TDD(Test Driven Development)测试驱动开发,是敏捷开发中提出的最 ...

  8. 网易云课堂_C++程序设计入门(上)_第6单元:丹枫虽老犹多态–继承与多态_第6单元作业【2】- 在线编程(难度:中)

    第6单元作业[2]- 在线编程(难度:中) 查看帮助 返回   温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提交答案,系统 ...

  9. 网易云课堂_C++程序设计入门(上)_第1单元:C++概览_第1单元作业 - 写代码 - 互评 (难度:易)

    第1单元作业 - 写代码 - 互评 (难度:易) 查看帮助 返回   提交作业(截止时间已过) 完成并提交作业     作业批改 互评训练   互评作业   自评作业     成绩公布 查看成绩 温 ...

随机推荐

  1. IB交换机配置命令总结

    串口通过远程CRT登录,波特率9600用户名和密码都是adminDo you want to use the wizard for initial configuration?选择no打开ip rou ...

  2. Bootstrap自带的一些预定义的按钮颜色

    浅蓝色 btn-info 被用在那些用户可能会采取的操作上. 红色btn-danger被用来提醒用户该操作具有“破坏性”,例如删除一张猫的图片.

  3. PowerPoint

    工具/原料 PowerPoint 2007 百度经验:jingyan.baidu.com 一.PowerPoint2007基础知识 1 桌面快捷方式:也可以“开始”菜单→程序→Microsoft Of ...

  4. 成都印迹婚纱摄影 | yinjilove.com

    成都印迹婚纱摄影工作室 官方网站:http://yinjilove.com/ 联系方式:028-84278563 手机及微信号:18180642817 微信公众号:印迹摄影 地址:成都市锦江区牛王庙东 ...

  5. 个人博客作业week2——代码复审

    1.代码规范 这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 代码规范并不是从官僚制度下产生,它是为了提高项目团队开发效率而产生的一种工具,能够极大的增强代码可读 ...

  6. Ubuntu下移植OpenCv

    通过近一周的时候终于成功交叉编译opencv成功了,真心不容易.有一句话乃真理也,凡事贵在坚持.过程总是痛苦的,因为不懂得很多问题但是又需要面对很多问题,最大的收获就是耐心解决所有问题后就懂得这些了. ...

  7. iOS 开发-- enum与typeof enum用法

    一, 两者的用法 枚举类型定义用关键字enum标识,形式为: enum标识符 { 枚举数据表 }; enum用来定义一系列宏定义常量区别用,相当于一系列的#define ** **,当然它后面的标识符 ...

  8. C# Retry重试操作解决方案(附源码)

    一.前言 (1)对于Thread的Abort方法,如果线程当前正在执行的是一段非托管代码,那么CLR就不会抛出ThreadAbortException,只有当代码继续回到CLR中时,才会引发Threa ...

  9. MariaDB+Keepalived双主高可用配置MySQL-HA

    利用keepalived构建高可用MySQL-HA,保证两台MySQL数据的一致性,然后用keepalived实现虚拟VIP,通过keepalived自带的服务监控功能来实现MySQL故障时自动切换. ...

  10. C#使用Timer.Interval指定时间间隔与指定时间执行事件

    C#中,Timer是一个定时器,它可以按照指定的时间间隔或者指定的时间执行一个事件. 指定时间间隔是指按特定的时间间隔,如每1分钟.每10分钟.每1个小时等执行指定事件: 指定时间是指每小时的第30分 ...