• JavaScript单元测试框架:Jasmine


    摘抄:http://blog.csdn.net/GuoJiangweigege/article/details/52130589

    互联网的快速发展,给web开发人员带来了前所未有的挑战。对于前端开发,前端开发er所需要编写的js早已不是那些寥寥几行的视觉效果代码。代码量的大增,多人协同,人员素质悬殊不齐,这都需要一个标准,来对代码的规范性进行控制。Jasmine作为一个前端团队使用的测试框架,便运应而生。

    1、jasmine简介

    jasmine是一个用来编写Javascript测试的框架,它不依赖于任何其它的javascript框架。它有拥有灵巧而明确的语法可以让你轻松的编写测试代码。目前最新的版本为2.0.0。

    在jasmine中,一个典型的单元测试起始于一个全局函数describe,describe包含了N个it函数,一个it函数包含N个断言。

    一个基本的测试代码如下:

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

    2、下载jasmine

    大家可以点击下面的链接进行下载:

    https://github.com/pivotal/jasmine/tree/master/dist

    推荐下载2.0.0版本的压缩包。

    解压之后,我们进入文件目录下的libjasmine-2.0.0,这下面通常包括以下这些文件。

    这些文件是我们进行js测试所需要的。

    3、jasmine的依赖

     

    jasmine的运行依赖4个部分:

     

    1) 运行环境
    浏览器(ie,Firefox,chrome)

     

    2) 源文件

     

    开发人员编写的js脚步

     

    3) 测试文件

     

    符合jasmineAPI的测试脚本

     

    4) 输出结果

     

    基于网页输出或控制台输出

     

    4、jasmine的使用

     

    我们在项目中新建test.html文件,主体代码如下:

    复制代码
    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8">
        <title>jasmine-js单元测试框架</title>
        <link rel="stylesheet" href="jasmine/jasmine.css">
        <script src="jasmine/jasmine.js"></script>
        <script src="jasmine/jasmine-html.js"></script>
        <script src="jasmine/boot.js"></script>
    </head>
    <body>
    <div>
        <p>js单元测试</p>
    </div>
    <script src="src.js"></script>
    <script src="test.js"></script>
    </body>
    </html>
    复制代码

    在页面中我们引入了5个js文件和1个css文件。

    jasmine.js : jasmine框架的核心文件。

    jasmine-html.js : 用于网页结果输出的js文件。

    boot.js : jasmine框架的的启动脚本。值得注意的是,这个脚本的执行应该在jasmine.js加载完成之后。

    src.js : 我们的业务逻辑脚本。

    test.js : jasmine测试脚本。 

    jasmine.css :控制网页结果输出的样式文件。

     

    
    ~ 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));
        });
    });
    

    页面报告截图:
    test1

    我们完成了,最基础的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函数。
    test2

    编辑src.js,增加reverse函数

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

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

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

    编辑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*.dd/);
                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完成各种的单元测试,下面是测试报告。
    test4

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

    转载请注明出处:

     

     

    5、API

    describe(string,function)

    全局函数,接收两个参数

    string:函数的描述

    function:测试组函数

    It(string,function)

    一个测试specs,接收两个参数

    string:spces的名称

    function:spces函数

    beforeEach(function)

    定义在一个describe的所有it执行前做的操作

    afterEach(function)

    定义在一个describe的所有it执行后做的操作

    toBe

    等同于===,比较变量

    toEqual

    处理变量,数组,对象等等

    toMatch

    使用正则式进行匹配

    toBeDefined

    是否已声明且赋值

    toBeUndefined

    是否未声明

    toBeNull

    是否null

    toBeTruthy   

    如果转换为布尔值,是否为true

    toBeFalsy    

    如果转换为布尔值,是否为false

    toContain   

    数组中是否包含元素(值)。只能用于数组,不能用于对象

    toBeLessThan   

    数值比较,小于

    toBeGreaterThan   

    数值比较,大于

    toBeCloseTo   

    数值比较时定义精度,先四舍五入后再比较

    toThrow    

    检验一个函数是否会抛出一个错误

    复制代码
    it("toThrow检验一个函数是否会抛出一个错误", function() {
        var foo = function() {
          return 1 + 2;
        };
        var bar = function() {
          return a + 1;
        };
        expect(foo).not.toThrow();
        expect(bar).toThrow();
    });
    复制代码

    jasmine中还有一个强大的spy函数,用它可以监控函数的调用情况,因为涉及的内容比较多且文章只是起到抛砖引玉的作用,所以我就不一一列举了,大家感兴趣可以到官网进行深入了解。

    官网链接:http://jasmine.github.io/2.0/introduction.html

  • 相关阅读:
    Python PEP8 编码规范中文版
    MySQL分区表
    mybatis缓存,包含一级缓存与二级缓存,包括ehcache二级缓存
    斐讯K2刷不死breed与第三方固件教程
    Mysql 多表连接查询 inner join 和 outer join 的使用
    mysql多表关联删除示例
    sublime Text 几款插件
    多进程vs多线程
    git 命令常用总结
    LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  • 原文地址:https://www.cnblogs.com/leolovexx/p/6598875.html
Copyright © 2020-2023  润新知