用jQuery Mobile制作記事本
在本系列教程的第一部分,將首先看下系統的整體設計,將完成如下的幾個步驟:
設計應用的總體架構;創建一個基本的用戶界面模型;使用Jasmine開發框架定義應用的公共接口;開始實現已定義的公共接口。
應用的總體架構
我們打算記事本應用能提供如下功能:創建記事;編輯記事內容;刪除記事內容;將記事的內容保存在移動客戶端中;查看所有已建立的記事列表。
主界面效果
首先我們要實現的是一個可以增加和編輯記事的界面,我們將這個界面命名為Note Editor。界面看上去應該是如下圖的樣子(下圖是個設計草稿圖):
此外,我們需要一個記事的列表的界面,以顯示已經存在的記事,這個是我們啟功應用程序時首先顯示給用戶的主界面,主界面如下所示:
接下來,看下如何使用BDD行為驅動的方式進行開發
使用Jasmine Framework框架進行為驅動開發
首先,我們將一步以實例的方式,一邊讓用戶體驗什么是行為驅動模式的開發。這種開發模式,能讓我們先行定義和測試業務邏輯,可以跟表現層進行分離地設計。先來看下如何使用Jasmine framework這個框架。
Jasmine是一個允許開發者使用行為驅動的方式對Javascript進行測試的框架。這意味著開發者可以使用類似自然語言(易于理解)的方式,通過Jasmine編寫測試用例,最后生成Javascript代碼,這樣明顯降低了開發的難度,甚至讓不是專業程序員的人也能讀懂和編寫。
下面快速舉一個例子來說明Jasmine框架的使用,更復雜的用法,請參考其官方網站的手冊,這個例子希望讀者能理解,我們將在教程中稍后會用到。
- describe("Notes functions", function () {
- it("Should return a NoteModel instance", function () {
- var note = Notes.app.createNote();
- expect(note instanceof Notes.model.NoteModel).toBeTruthy();
- });
- });
在這個例子中,我們使用了多種Jasmine框架的特性。其中一個函數方法就是describe(),這個函數用來創建一個包含所有相關的測試的規格說明,我們稱之為測試套件。
其中,一個測試規格說明是通過函數方法it()中聲明的。當調用it()方法時,要傳遞一個字符串參數進去,比如這里,我們期待代碼能創建并返回一個NoteModel的實例。
接下來,我們通過 var note = Notes.app.createNote();創建了NoteModel的實例,然后使用了expect()函數這個斷言(在單元測試中我們稱之為斷言),這里是斷言判斷note是否為Notes.model.NoteModel的一個實例,并使用toBeThruthy()這個匹配器去判斷這個測試用例是否能正確通過測試。關于匹配器請參考(https://github.com/pivotal/jasmine/wiki/Matchers )。
小結一下,在it()這個函數中,開發者可以編寫相關的代碼建立測試用例,并可以多次調用expect()方法。
#p#
Jasmine的使用步驟
下面我們開始正式使用Jasmine 框架,首先我們來看下其目錄結構。首先我們為項目創建一個名為NoteApp的文件夾。在這個主文件夾下,再創建一個名為app的目錄,這個目錄中將存放的是程序的應用邏輯和表示層的頁面文件。創建一個名為spec的目錄,這個目錄中存放的是Jasmine的測試套件。除此之外,我們還創建一個lib的目錄,這個目錄保存的是項目中要用到的一些目錄,整個目錄架構如下圖:
在上圖中,讀者可能奇怪jqm和jstorage兩個文件夾存放的是什么,jqm存放的是jquery mobile的框架文件,而jstorage存放的是jstorage框架的文件,在接下來的學習中將會詳細介紹。
接著,我們可以將下載到的jasmine框架的文件解壓后,放到jasmine目錄下,如下圖:
接下來,我們開始編寫應用的第一個代碼文件,一個是名為app.js,放在app目錄下,另外一個是jasmine的測試程序,文件為Appsec.js,文件的保存位置如下圖:
最后,我們將編寫一個名為specrunner.html的文件,這個文件中將會運行調用jasmine的測試用例。這個文件實際在jasmine的下載包中存在,但我們要對其進行一些必要的修改,以使其引用到恰當的類庫文件,代碼如下:
- <!-- HEAD -->
- <!-- Jasmine includes -->
- css" rel="stylesheet" type="text/css" />
- <script type="text/javascript"
- src="../lib/jasmine/jasmine-html.js" type="text/javascript">
- </script>
- <!-- Source files -->
- <script src="app/App.js" type="text/javascript"></script>
- <!-- Spec files -->
- <script src="spec/AppSpec.js" type="text/javascript"></script>
- <!-- BODY -->
- <script type="text/javascript">
- jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
- jasmine.getEnv().execute();
- </script>
最后,我們把這個文件放到恰當的位置,如下圖:
#p#
開始編寫邏輯代碼
接下來,我們開始使用jasmine框架以BDD驅動方式編寫主要的代碼。BDD的方式需要我們不斷編寫和修改單元測試用例AppSec.js,讓我們就從AppSec.js這個文件開始吧。
首先,我們必須斷言命名空間是存在的,所以可以在AppSec.js文件中,編寫如下代碼:
- describe("Public interface exists", function () {
- it("Defines the app", function () {
- expect(Notes.app).toBeDefined();
- });
- });
注意我們在一個名為Public interface exists的測試套件中,編寫了測試說明用例。在這個測試套件中,將保存所有對業務邏輯的公共函數測試的用例,這里只是簡單去斷言應用的命名空間是否已經定義。
接下來我們開始進行測試,使用瀏覽器中打開specrunner.html這個文件,可以看到如下圖的結果:
可以看到,出現了錯誤的提示:Notes is not defined。這是正確的,因為我們的代碼中還沒定義命名空間,接下來我們編寫代碼修正之,如下:
- var NotesNotes = Notes || {}
- Notes.app = (function () {
- return {}
- })();
這里我們定義了應用的命名空間,再次運行jasmine測試框架,結果如下圖:
現在我們可以總結出其步驟:先定義出行為,然后為行為編寫測試用例,然后運行測試,看測試是否通過,不通過的話就修改代碼,再運行測試直到其再次通過,這就是典型的BDD開發方法。
接下來,我們需要將一些記事的內容列表由業務邏輯端返回給前端的表現層,因此我們使用如下的jasmine的行為規格說明去定義,繼續往測試套件中增加如下代碼:
- describe("Public interface exists", function () {
- it("Should have public interface to return notes list", function () {
- expect(Notes.app.getNotesList).toBeDefined();
- });
- });
這個測試用例斷言測試是否已經定義了顯示記事列表的方法getNotesList。再編寫另外一個測試用例,稍微復雜點的,如下:
- describe("Public interface implementation", function () {
- it("Should return notes list", function () {
- var notesList = Notes.app.getNotesList();
- expect(notesList instanceof Array).toBeTruthy();
- });
- });
這個測試用例,主要用來斷言測試返回的記事列表是否是一個數組。 注意我們現
在新建立了一個測試套件,名為 Public interface implementation,在這個測試套件中,專門存
放的是針對接口實現的測試用例。再次在瀏覽器中運行,可以看到如下圖:
可以看到,兩個測試用例都出錯了,沒關系,我們馬上編寫代碼修正:
- Notes.app = (function () {
- var notesList = [];
- function getNotesList() {
- return notesList;
- }
- return {
- getNotesList: getNotesList
- }
- })();
再次運行測試,結果如下圖,這次我們通過了測試。
接下來的步驟
接下來,我們將使用jQuery Mobile開始正式開始編寫我們的業務邏輯層代碼了。請留意本教程系列的第2講。
原文鏈接:http://www.byhtml5.com/hjc/2012-01-20/504_7.html
【編輯推薦】