這篇主要是要來學習 angularjs 的單元測試方式,其實本來想拖到最後面再來學的

但是不管是看AngularJS 官網還是看書,照步驟的話單元測試都是在前幾章.....orz

所以就先硬著頭皮學一下....但學完之後才發現其實還蠻簡單,建立個測試花不了多少時間

不過因為我是用 .net 所以這篇要學的是如何用 visual studio 對 angularjs 做單元測試

不是用 .net 可以參考官網

官網 : https://docs.angularjs.org/guide/unit-testing

反正語法都一樣是 jasmine,只有環境建置不太一樣

 

安裝

要在 visual studio 上做單元測試,首先安裝一下 Chutzpah 延伸套件,到 Nuget 上搜尋 Chutzpah

會看到 Chutzpah - A JavaScript Test Runner 就把它裝起來

擷取     

底下也有個 jasmine.js 也把它裝起來,我們就是要用這個框架來做單元測試

官網的範例也是利用 jasmine 來做測試的,所以相關的語法範例也可以看看官網

unit-testing : https://docs.angularjs.org/guide/unit-testing

插花了一下,繼續安裝......

兩個都裝起來後再來裝 Chutzpah Test Runner Context Menu Extension

https://visualstudiogallery.msdn.microsoft.com/71a4e9bd-f660-448f-bd92-f5a65d39b7f0

要裝這個你才能對著檔案按滑鼠右鍵直接 run 測試,下載安裝之後重新啟動 Visual Studio 就完成了 

再來建立一個要做單元測試的資料夾,取個名字叫做 JsUnitTest 好了,所以資料夾結構如下 :

擷取   

JS資料夾底下有一隻 home.js 是等下要測試的 angularjs controller 的所在檔案

而我們在 JsUnitTest 下面新增了一隻空白的 js 檔叫做 T1.tests.js (你要叫什麼名字都可以)

準備來開始在裡面寫單元測試的測試專案~

 

開始寫單元測試

我們要測試的 module 跟 controller (home.js) 是下面這個簡單的範例

angular.module("myapp", []).controller("mycontroller", [function () {
var self = this;
function getnote() {
var note = [
{ id: "1" },
{ id: "2" },
{ id: "3" },
{ id: "4" }
]
return note;
}
self.note = getnote();
}]);

再來就開始寫測試檔,先寫完再解釋

/// <reference path="../../angularjs/js/angularjs.js" />
/// <reference path="d:\angularjs\library\scripts\jasmine.js" />
/// <reference path="d:\angularjs\library\scripts\jasmine-html.js" />
/// <reference path="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-mocks.js" />
/// <reference path="../../angularjs/js/home.js" />
 
describe("angularjs 單元測試", function () {
beforeEach(module("myapp"));
//測試 case 1 模擬成功條件
it("測試controller中note 陣列第1個id值是否為2", inject(function ($controller) {
var ctrl = $controller("mycontroller");
expect(ctrl.note[1].id).toEqual('2');
}));
//測試 case 2 模擬失敗條件
it("測試controller中note長度是否為2", inject(function ($controller) {
var ctrl = $controller("controller");
expect(ctrl.note.length).toEqual(2);
}));
});
 

解說 : 

在 vs.net 使用 jasmine 的語法做單元測試,必須要先透過 <reference path="..." /> 來載入相關的 js 檔案

不用擔心引用很麻煩,基本上就是從方案總管拉過來就好了,會自動產生 /// <reference> 標籤

以上面的範例為例 : 

引用 angularjs 的核心
<reference path="../../angularjs/js/angularjs.js" />
 
引用準備要進行單元測試的 js 
<reference path="../../angularjs/js/home.js" />
 
引用下面這兩隻的話,在 visual studio 上就有 Intellisense 可以用了
<reference path="d:\angularjs\library\scripts\jasmine.js" />
<reference path="d:\angularjs\library\scripts\jasmine-html.js" />
 
引用 angular-mocks 是為了使用 angularjs 所提供單元測試的程式庫
例如上面的 inject 就是 mock 提供的功能
<reference path="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-mocks.js" />

 

再來說明測試程式碼,大部分是 jasmine 的語法,不過都很好懂,而且也沒幾個 

describe("angularjs 單元測試", function () {
beforeEach(module("myapp"));
//測試 case 1 模擬成功條件
it("測試controller中note 陣列第1個id值是否為2", inject(function ($controller) {
var ctrl = $controller("mycontroller");
expect(ctrl.note[1].id).toEqual('2');
}));
//測試 case 2 模擬失敗條件
it("測試controller中note長度是否為2", inject(function ($controller) {
var ctrl = $controller("controller");
expect(ctrl.note.length).toEqual(2);
}));
});

 

describe 

使用 describe 可以建立一組測試套件(測試專案),用來當作多組單元測試的容器

describe("angularjs 單元測試", function () {

// 單元測試

});

擷取   

測試容器的名稱也會顯示在上圖測試總管畫紅框的位置

 

beforeEach 

在執行 it (下面會講到) 之前會將 beforeEach 裡的敘述執行一次

以上面的程式碼為例 :

beforeEach(module("myapp"));

代表在執行單元測試之前透過 angularjs 提供的 mock 程式庫來載入你要測試的 module

就是載入 home.js 裡那個名為 myapp 模組的意思

 

afterEach 

上面這個例子沒用到 afterEach 

有 beforeEach 也會有一個 afterEach,beforeEach 是在執行單元測試之前執行

afterEach 則是在單元測試執行完之後執行

一般是用來檢查單元測試中,模擬預期狀況是否符合的最好地方

 

it 

it 內的區塊就是單元測試真正的內容,每個單元測試區塊都是獨立的囉

在單元測試區塊中則會有 expect 命令來檢查所有預期內容是否得到滿足

以上面的例子一步一步來看

ex : 

it("測試controller中note 陣列第1個id值是否為2", inject(function ($controller) {

var ctrl = $controller("mycontroller");

}));

上面的範例 it 就代表一個單元測試區塊,第一個參數是單元測試名稱

此例而言就是 "測試controller中note 陣列第1個id值是否為2",如下圖測試總管紅框的文字

擷取   

第二個參數使用了 mock 函式庫中的 inject 來注入服務 (此例是 $controller)

mock 的 inject 可以參考官網 : https://docs.angularjs.org/api/ngMock/function/angular.mock.inject

下面再來用 $controller 這 service 來實體化 controller 

var ctrl = $controller("mycontroller");

mycontroller 就是我們要測試的 controller 名稱,透過 $controller 來實體化

然後這個注入的動作以後也可以寫在 beforeEach 裡面,例如這樣

var ctrl;
beforeEach(inject(function($controller){
ctrl = $controller("mycontroller");
})); 
it("測試一",function() {
//......
}); 

就不用以後每個 it 都要 inject 一次

 

expect 

expect 用來檢查所輸入的值是否有符合預定的期望值,輸入參數只有一個就是要檢查的值

ex : 

expect(ctrl.note[1].id).toEqual('2');

上面這個例子檢查了 ctrl.note[1].id 是否等於 '2' 

除了 toEqual,jasmine 也提供了多個 matchers 來供使用

下面就直接列出來參考一下喔!

toEqual  

比較物件是否相等 (所有欄位與其值都必須匹配)

toBe

為引用 (reference) 做檢查,且預期傳遞給 expect 與 matcher 的兩個項目會是完全相同的物件引用

toBeTruthy

檢查是否為 true,其中空的物件、非空白字串、非零、true 都會被認為是 truthy (真值)

toBeFalsy

跟上面反過來,null、undefined、空白字串、零、false 都會被認為是 falsy (假值)

toBeDefined

檢查確保是有被定義的 

toBeUndefined 

檢查是未定義 

toBeNull

檢查是 null

toContain 

檢查傳遞給 expect 的陣列是否包含傳遞給 toContain 的項目

toMatch 

第一個參數是用來做正規表示式的檢查

 

Jasmine Matcher 官網 :

http://jasmine.github.io/2.0/custom_matcher.html

 

寫完單元測試之後就可以在 visual studio 的測試總管看到測試的專案了

擷取   

或是剛剛有裝 Chutzpah Test Runner Context Menu Extension 的話

https://visualstudiogallery.msdn.microsoft.com/71a4e9bd-f660-448f-bd92-f5a65d39b7f0

也可以對著要測試的檔案按滑鼠右鍵 Run JS Tests 直接測試了

Clipboard01   

嗯.....就這麼簡單~

 

參考資料 : 

官網 : https://docs.angularjs.org/guide/unit-testing

網站 : http://blog.darkthread.net/post-2014-06-17-angularjs-notes-4-unit-test.aspx

書 : AngularJS 建置與執行 

 

AngularJS 學習筆記系列 : (依本人的上進心持續增加)

AngularJS 初學者筆記與教學 (一) - 使用方式、Expression、Controller、Module

AngularJS 初學者筆記與教學 (二) 內建的簡單指令之1 ng-click、ng-show、ng-hide

AngularJS 初學者筆記與教學 (三) - AngularJS 的載入流程與 ng-cloak 運作原理 

AngularJS 初學者筆記與教學 (四) - 如何動態改變 CSS 樣式,使用 ng-class、ng-style

AngularJS 初學者筆記與教學 (五) - 繼續深入學習常用的 ng-repeat

AngularJS 初學者筆記與教學 (六) - 單元測試

AngularJS 初學者筆記與教學 (新手入門課程 - 課後心得篇)

創作者介紹
創作者 小雕 的頭像
小雕

小雕雕的家

小雕 發表在 痞客邦 留言(0) 人氣()