单元测试 jasmine

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。所以,不要被新名词吓到,实质是一样的。

时间: 2024-08-12 12:06:07

单元测试 jasmine的相关文章

Grunt - Karma 单元测试

Karma 是 Goolge 开源的一个 Test runner, 可以配合 Grunt 使用. 1. 相关插件介绍 1.1 Karma 的官网 http://karma-runner.github.io/ 官网中的文档其实分多钟版本,不同版本的 karma 使用也有所不同,注意页面右上角的版本信息. 1.2 配合 Grunt 的插件 grunt-karma https://github.com/karma-runner/grunt-karma 1.3 karma 用来启动 chrome 的 k

Angular单元测试与E2E测试

本文介绍了Angular单元测试和E2E测试的配置与测试方法.示例APP使用Angular 7 CLI创建,已配置好基础测试环境,生成了测试样例代码.默认,Angular单元测试使用Jasmine测试框架和Karma测试运行器,E2E测试使用Jasmine测试框架和Protractor端到端测试框架. 配置单元测试 Jasmine是一个用于测试JavaScript的行为驱动开发框架,不依赖于任何其他JavaScript框架.Karma是测试运行器,为开发人员提供了高效.真实的测试环境,支持多种浏

angular2单元测试学习

单元测试简介:https://segmentfault.com/a/1190000009737186 单元测试-Jasmine:https://segmentfault.com/a/1190000009737204 angular2单元测试:https://segmentfault.com/a/1190000009769787#articleHeader1 概念简介 Jasmine Jasmine测试框架提供了编写测试脚本的工具集,而且非常优秀的语义化,让测试代码看起来像是在读一段话. desc

闻名遐迩JavaScript库总结

目录 DOM (操作)相关库 AccDC Dojo Toolkit Glow jQuery midori MooTools Prototype JavaScript Framework YUI Library 界面相关库 (窗口部件库) Ample SDK DHTMLX Dojo Widgets Ext JS iX Framework jQuery UI Lively Kernel qooxdoo Script.aculo.us SmartClient 图形/可视化 (Canvas 或SVG 相

Web前端开发

由于互联网的各种兴起,网页开发似乎也火了,催生了github上各种js的轮子,各种重复,各种框架和库,什么Jquery,bootstrap等等.面对这么多框架和库我们在工程上该如何取舍(trade-off)呢?每个框架的诞生基本上都会有它自己的“新概念”,主要是解决一些问题.比如如果你原生js写的多,很多重复的操作写得枯燥麻烦了,你可以考虑用Jquery,因为Jquery就是一些经典的,常用的js代码集合,也就是帮你封装了很多功能,其实它主要是一个DOM的Wrapper,以DOM操作为核心的库.

《DevOps实践:驭DevOps之力强化技术栈并优化IT运行》

DevOps实践:驭DevOps之力强化技术栈并优化IT运行 主旨 这本书并非坐而论道,而是介绍了DevOps全流程中的许多实践,以及相应工具的运用.虽然随着时代的推移,工具将来可能会过时,但是这些实践的应用和相应的方法是不会过时的,所以对于其中各种实践必要性和相关方法的讲解,是特别值得注意的.作者认为一切皆代码,所以各个章节是围绕代码的生命周期展开的,提到了这些环节的实践: 管理代码 构建代码 测试代码 部署代码 监控代码 DevOps和持续交付简介 DevOps的由来 Patrick Deb

Angularjs 基于karma和jasmine的单元测试

目录: 1. 单元测试的配置 2. 实例文件目录解释 3. 测试controller     3.1 测试controller中变量值是否正确     3.2 模拟http请求返回值,测试$http服务相关 4. 从文件中读取json,来模拟 http请求返回数据 5. 测试返回promise的service 已经有很多教程提到了angularjs项目的单元测试,但大都不是很全,如一些入门的文章,介绍了测试http service 却没有介绍如何从文件中读取测试数据来仿真.一些介绍如何从文件中读

基于karma和jasmine的Angularjs 单元测试

Angularjs 基于karma和jasmine的单元测试 目录: 1. 单元测试的配置 2. 实例文件目录解释 3. 测试controller     3.1 测试controller中变量值是否正确     3.2 模拟http请求返回值,测试$http服务相关 4. 从文件中读取json,来模拟 http请求返回数据 5. 测试返回promise的service 已经有很多教程提到了angularjs项目的单元测试,但大都不是很全,如一些入门的文章,介绍了测试http service 却

使用karma+jasmine做单元测试

目的 使用karma和jasmine来配置自动化的js单元测试. Karma和Jasmine Karma是由Angular团队所开发的一种自动化测试工具.链接:http://karma-runner.github.io/ Karma会启动PhantomJS实例来运行测试,可以在其上使用Jasmine.Mocha等测试框架,也可以和Jenkins.Travis等CI(Continuous Integration,持续集成)进行整合. Jasmine是一个按照BDD(behavior-driven