[料理佳餚] 用 Jasmine 撰寫一個 JavaScript 的單元測試

對我來說寫測試有一個很大的目的就是「保護既有已完善的程式碼」,我開發的 jQuery 擴充套件 - jquery-model 已經被我們團隊成員接受並廣泛使用,為了保護自己也保護他人,是時候為它投入一些時間架設防護網,而 JavaScript 的單元測試框架有好幾款,我選擇了 Jasmine,為啥呢? 因為它在官網的 GETTING STARTED 頁面就告訴我如果用 STANDALONE 的發行版本來引用 Jasmine,僅此而已。

引用 STANDALONE 的發行版本

到 Jasmine 的 GitHub Release Page 挑選一個自己想要的版本下載下來,我這邊下載的版本是 3.5.0,解壓縮之後,直接在 HTML 中引用就行了,語法如下:

<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-{#.#.#}/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-{#.#.#}/jasmine.css">

<script type="text/javascript" src="jasmine/lib/jasmine-{#.#.#}/jasmine.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-{#.#.#}/jasmine-html.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-{#.#.#}/boot.js"></script>

起手式

如果曾經使用過其他測試框架的話,使用上大同小異,概念差不多,首先用 describe() 方法定義測試集(Test Suite)。

describe("test suite", function () {
    // ...
});

it() 方法來撰寫一個單元測試

describe("test suite", function () {

    it("test case", function () {
        // ...
    });
    
});

斷言(Assertion)

測試框架一定缺少不了斷言(Assertion)的語法,Jasmine 的斷言需要將目標對象先透過 expect() 方法包裝過,再呼叫 matchers,matchers 的呼叫就接在 expect() 方法的後面。

expect(actual).toBe(expected);

這邊介紹幾個常用的 matchers,想要知道更多的話就請到 Jasmine 的官網查看。

  • toBe()
  • not
  • toBeUndefined()
  • toBeTrue()
  • toBeFalse()
  • toBeGreaterThan()
  • toBeGreaterThanOrEqual()
  • toBeLessThan()
  • toBeLessThanOrEqual()
  • toBeInstanceOf()
  • toContain()

底下介紹幾個我覺得很特別的 matcher

  • toMatch():進行 Regular Expression 比對
  • toEqual():進行 object 的比對
  • toBeTruthy() / toBeFalsy():使用 == 而非 === 進行比對

測試前後的事件註冊

執行測試時,時常會有一些工作需要在測試前或測試後執行,比如:測試資料的初始化,這方面 Jasmine 提供了四個方法:afterAll()afterEach()beforeAll()beforeEach(),下面就來說明一下差異。

  • afterAll() / beforeAll():會在所有測試案例執行前後執行,只會執行一次。
  • afterEach() / beforeEach():會在每一個測試案例執行前後執行,會執行多次。

xdescribe / xit

如果我們希望哪一個測試集或測試案例不要執行,只要在前面加個 x 就行了。

xdescribe("test suite", function () {

    xit("test case", function () {
        // ...
    });
    
});

寫一個單元測試

對 Jasmine 有了基本的了解之後,我們就可以來寫測試了,以我開發的 jquery-model 為例,其中一個是我要測試 model() 這個方法在 text input 能不能正常運作?

describe("jquery-model test suite", function () {

    it("Test_TextInput_can_Set_and_Get_Text_and_Number_value", function () {
        var $container = $("#container");

        $container.model({ id: 1, name: "Johnny" });

        var model = $container.model();

        expect(model.id).toBe(1);
        expect(model.name).toBe("Johnny");
    });
    
});

測試寫好後,記得在 HTML 中引用。

用瀏覽器瀏覽測試頁面,Jasmine 就會執行測試,並且顯示簡單的測試報告。

以上,關於 Jasmine 的介紹先到這邊,它其實還有像是 SpyClock、...等一些為了更進階測試而生的 API,待將來有機會再跟各位朋友分享。

參考資料

 
C# 指南 ASP.NET 教學 ASP.NET MVC 指引
Azure SQL Database 教學 SQL Server 教學 Xamarin.Forms 教學