本文来自http://blog.fens.me/nodejs-jasmine-bdd 粉丝日志 张丹


 

前言
TDD(Test Driven Development)测试驱动开发,是敏捷开发中提出的最佳实践之一。jasmine很有意思的提出了BDD(Behavior Driven Development)行为驱动开发,诱发了我的好奇心,一探究竟。

测试驱动开发,对软件质量起到了规范性的控制。未写实现,先写测试,一度成为Java领域研发的圣经。随着Javascript兴起,功能越来越多,代码量越来越大,开发人员素质相差悬殊,真的有必要建立对代码的规范性控制。jasmine就是为团队合作而生。

目录

  1. jasmine介绍
  2. jasmine安装
  3. jasmine环境配置
  4. jasmine使用

1. jasmine介绍

Jasmine是一个用来编写Javascript测试的框架,它不依赖于任何其它的javascript框架,也不需要对DOM。它有拥有灵巧而明确的语法可以让你轻松的编写测试代码。

jasmine的结构很简单:


describe("A suite", function() {
var foo;
beforeEach(function() {
foo = 0;
foo += 1;
}); afterEach(function() {
foo = 0;
}); it("contains spec with an expectation", function() {
expect(true).toBe(true);
});
});

每个测试都在一个测试集中运行,Suite就是一个测试集,用describe函数封装。 Spec表示每个测试用例,用it函数封装。通过expect函数,作为程序断言来判断相等关系。setup过程用beforeEach函数封装,tearDown过程用afterEach封装。

用过Java中JUnit的同学,看到这种对应关系,应该就会明白jasmine就是JUnit的Javascript重写版。

2. jasmine安装

安装jasmine类库时,让我们利用bower,一键搞定。bower的使用介绍,请参考文章:bower解决js的依赖管理。把已经学到的知识用起来,效率马上提升10倍。


~ D:\workspace\javascript>mkdir jasmine
~ D:\workspace\javascript>cd jasmine #查找jasmine项目
~ D:\workspace\javascript\jasmine>bower search jasmine
-----------------------------------------
Update available: 1.2.4 (current: 1.1.2)
Run npm update -g bower to update
----------------------------------------- Search results: jasmine git://github.com/pivotal/jasmine.git
jasmine-jquery git://github.com/velesin/jasmine-jquery
jasmine-sinon git://github.com/froots/jasmine-sinon.git
jasmine-ajax git://github.com/pivotal/jasmine-ajax.git
jasmine.async git://github.com/derickbailey/jasmine.async.git
flight-jasmine git://github.com/twitter/flight-jasmine.git
jasmine-jstd-adapter git://github.com/ibolmo/jasmine-jstd-adapter.git
jasmine-flight git://github.com/flightjs/jasmine-flight.git
jasmine-signals git://github.com/AdamNowotny/jasmine-signals.git
jasmine-underscore git://github.com/adscott/jasmine-underscore.git
jasmine-bootstrap git://github.com/esbie/jasmine-bootstrap.git
jasmine-data-provider git://github.com/sublimino/jasmine-data-provider.git
jasmine-sugar git://github.com/fantactuka/jasmine-sugar.git #安装jasmine类库
~ D:\workspace\javascript\jasmine>bower install jasmine
bower jasmine#* not-cached git://github.com/pivotal/jasmine.git#*
bower jasmine#* resolve git://github.com/pivotal/jasmine.git#*
bower jasmine#* download https://github.com/pivotal/jasmine/archive/v1.3.1.tar.gz
bower jasmine#* extract archive.tar.gz
bower jasmine#* resolved git://github.com/pivotal/jasmine.git#1.3.1
bower jasmine#~1.3.1 install jasmine#1.3.1 jasmine#1.3.1 bower_components\jasmine

3. jasmine环境配置

jasmine运行需要4个部分:

  • 1. 运行时环境:我们这里基于chrome浏览器,通过HTML作为javascript载体
  • 2. 源文件:用于实现某种业务逻辑的文件,就是我们平时写的js脚本
  • 3. 测试文件:符合jasmineAPI的测试js脚本
  • 4. 输出结果:jasmine提供了基于网页的输出结果

下面让我开始jasmine:

1). 新建一个HTML文件:test.html

~ vi test.html

<!DOCTYPE html>
<html>
<head>
<title>jasmine test</title>
<link rel="stylesheet" type="text/css" href="bower_components/jasmine/lib/jasmine-core/jasmine.css">
<script type="text/javascript" src="bower_components/jasmine/lib/jasmine-core/jasmine.js"></script>
<script type="text/javascript" src="bower_components/jasmine/lib/jasmine-core/jasmine-html.js"></script>
</head>
<body>
<h1>jasmine test</h1>
<script type="text/javascript" src="src.js"></script>
<script type="text/javascript" src="test.js"></script>
<script type="text/javascript" src="report.js"></script>
</body>
</html>

我们看到页面上面有5个javascript的导入:

  • jasmine.js:核心文件用于执行单元测试的类库
  • jasmine-html.js:用于显示单元测试的结果的类库
  • src.js:我们自己的业务逻辑的js
  • test.js:单元测试的js
  • report.js:用于启动单元测试js

jasmine.js,jasmine-html.js是系统类库,直接引入。
report.js,是启动脚本,写法是固定的。


~ vi report.js (function() {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000; var htmlReporter = new jasmine.HtmlReporter(); jasmineEnv.addReporter(htmlReporter); jasmineEnv.specFilter = function(spec) {
return htmlReporter.specFilter(spec);
}; var currentWindowOnload = window.onload; window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
}; function execJasmine() {
jasmineEnv.execute();
} })();

src.js是实现业务逻辑的文件,我们定义sayHello的函数


~ vi src.js function sayHello(name){
return "Hello " + name;
}

test.js对源文件进行单元测试


~ vi test.js describe("A suite of basic functions", function() {
var name; it("sayHello", function() {
name = "Conan";
var exp = "Hello Conan";
expect(exp).toEqual(sayHello(name));
});
});

页面报告截图:

我们完成了,最基础的jasmine功能。

4. jasmine使用

1). 测试先行
测试先行,就是未写现实,先写用例。

我们刚才已经配置好了jasmine的环境,后面我们所有功能代码都写在src.js中,测试代码都写在test.js中。

有一个需求,要实现单词倒写的功能。如:”ABCD” ==> “DCBA”

我们编辑test.js,增加一个测试用例


~ vi test.js it("reverse word",function(){
expect("DCBA").toEqual(reverse("ABCD"));
});

执行这个页面,单元测试失败,提示没有reverse函数。

编辑src.js,增加reverse函数


function reverse(name){
return "DCBA";
}

执行页面,单元测试成功!

单元测试成功,是不是能说明我们完成了“单词倒写”的功能呢?答案是不确定的。如果想保证功能是正确性,我们需要进行更多次的验证。

编辑test.js,继续增加测试用例


it("reverse word",function(){
expect("DCBA").toEqual(reverse("ABCD"));
expect("Conan").toEqual(reverse("nanoC"));
});

刷新页面,又提示单元测试失败,因为我们希望输入是”Conan”,输出是”nanoC”,但是功能代码返回是”DCBA”,显然业务逻辑写的是不对的。

修改src.js,修改reverse函数


~ vi src.js function reverse(name){
return name.split("").reverse().join("");
}

再次刷新页面,单元测试成功!!

这是敏捷开发中提倡的“测试先行”的案例,对于产品级的代码,我们真的应该要高质量控制。

2). jasmine语法实践
以下内容是对jasmine语法的介绍,都在test.js中实现。

做一个嵌套的describe(“A suite of jasmine’s function”)

对断言表达式的使用


describe("A suite of jasmine's function", function() {
describe("Expectations",function(){
it("Expectations",function(){
expect("AAA").toEqual("AAA");
expect(52.78).toMatch(/\d*.\d\d/);
expect(null).toBeNull();
expect("ABCD").toContain("B");
expect(52,78).toBeLessThan(99);
expect(52.78).toBeGreaterThan(18); var x = true;
var y;
expect(x).toBe(true);
expect(x).toBeDefined();
expect(y).toBeUndefined();
expect(x).toBeTruthy();
expect(!x).toBeFalsy(); var fun = function() { return a + 1;};
expect(fun).toThrow();
});
});
});

对开始前和使用后的变量赋值


describe("Setup and Teardown",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);
});
});

对忽略suite的声明


xdescribe("Disabling Specs and Suites", function() {
it("Disabling Specs and Suites",function(){
expect("AAA").toEqual("AAA");
});
});

对异步程序的单元测试


describe("Asynchronous Support",function(){
var value, flag;
it("Asynchronous Support", function() {
runs(function() {
flag = false;
value = 0;
setTimeout(function() {
flag = true;
}, 500);
});
waitsFor(function() {
value++;
return flag;
}, "The Value should be incremented", 750); runs(function() {
expect(value).toBeGreaterThan(0);
});
});
});

我们成功地对Javascript完成各种的单元测试,下面是测试报告。

最后,BDD其实就是TDD。所以,不要被新名词吓到,实质是一样的。

jasmine入门的更多相关文章

  1. Jasmine入门(下)

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

  2. Jasmine入门(上)

    什么是Jasmine Jasmine是一个Javascript的BDD(Behavior-Driven Development)测试框架,不依赖任何其他框架. 如何使用Jasmine 从Github上 ...

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

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

  4. [Vue] karme/jasmine/webpack/vue搭建测试环境

    karma 和 jasmine karma 是 google 开源的一个基于 Node.js 的 JavaScript 前端测试运行框架,前身叫 Testacular. jasmine 是一个 jav ...

  5. ApacheCN JavaScript 译文集 20211122 更新

    JavaScript 编程精解 中文第三版 零.前言 一.值,类型和运算符 二.程序结构 三.函数 四.数据结构:对象和数组 五.高阶函数 六.对象的秘密 七.项目:机器人 八.Bug 和错误 九.正 ...

  6. angularjs+jasmine单元测试入门

    使用cordova.angularjs.ionic开发hybrid App有一段时间了.为了做单元测试,之前一直是把要测的某一部分产品代码复制到另一个单独的工程中来写测试代码,测好了以后再复制回去.弊 ...

  7. karma单元测试入门

    学习angularjs,都会遇到karma单元测试,可是初学者面对复杂的测试配置往往不知从何入手,下面我们将抛开angularjs,单独使用两个js文件,完成一次测试入门. 0,karma原理

  8. angular测试-Karma + Jasmine配置

    首先讲一下大致的流程: 需要node环境,首先先要安装node,node不会?请自行搜索.版本>0.8 安装node完成之后先要测试下npm是否测试通过,如下图所示 首先看下目录结构 目录为:F ...

  9. PhantomJS快速入门

    本文简要介绍了PhantomJS的相关基础知识点,主要包括PhantomJS的介绍.下载与安装.HelloWorld程序.核心模块介绍等.由于鄙人才疏学浅,难免有疏漏之处,欢迎指正交流. 1.Phan ...

随机推荐

  1. swift 3.0 协议笔记

    协议能够要求遵循者必须含有一些特定名称和类型的实例属性(instance property)或类属性(type property),也能够要求属性的(设置权限)settable 和(访问权限)gett ...

  2. _NSInlineData objectForKeyedSubscript:

    最近总是遇到这个错误:reason: '-[_NSInlineData objectForKeyedSubscript:]: unrecognized selector sent to instanc ...

  3. [转]程序员趣味读物:谈谈Unicode编码

    from : http://pcedu.pconline.com.cn/empolder/gj/other/0505/616631_all.html#content_page_1 这是一篇程序员写给程 ...

  4. Java中的URL类

    Java的网络类可以让你通过网络或者远程连接来实现应用.而且,这个平台现在已经可 以对国际互联网以及URL资源进行访问了.Java的URL类可以让访问网络资源就像是访问你本地的文件夹一样方便快捷.我们 ...

  5. CSS中定义CLASS时,中间有空格和没空格的区别是什么?

    .example .pp{ color: orange; } .example.pp2 { color: green; }如上面的两个定义一个是中间有空格,一个是中间没空格. 第一个class要这样写 ...

  6. EXT.JS的PROXY放在哪里,STORE放在哪里,绝对是个技术活儿啊。

    我理解的是,单独的STORE,会在应用程序开始时就加载, 而VIEWMODEL的STORE,会在VIEW加载时才开始加载. PROXY放在STORE,则会在调用这个STORE的VIEW才能请求服务器数 ...

  7. Hadoop单机模式安装-(3)安装和配置Hadoop

    网络上关于如何单机模式安装Hadoop的文章很多,按照其步骤走下来多数都失败,按照其操作弯路走过了不少但终究还是把问题都解决了,所以顺便自己详细记录下完整的安装过程. 此篇主要介绍在Ubuntu安装完 ...

  8. 安装Python环境时遇到的问题

    问题描述:An error occurred during the installation of assembly 'Microsoft.VC90.MFC,version="9.0.210 ...

  9. HTML5 五子棋 - JS/Canvas 游戏

    背景介绍 因为之前用c#的winform中的gdi+,java图形包做过五子棋,所以做这个逻辑思路也就驾轻就熟,然而最近想温故html5的canvas绘图功能(公司一般不用这些),所以做了个五子棋,当 ...

  10. linux中redis安装

    一.登录redis官网下载redis-3.0.7.tar.gz 二.通过ftp工具上传至自己的服务器中 三.tar -zxvf redis-3.0.7.tar.gz解压 四.cd redis-3.0. ...