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版本的壓縮包。

解壓之后,我們進入文件目錄下的lib\jasmine-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*.\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完成各種的單元測試,下面是測試報告。
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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM