花費數小時後,也許>天> ,為您的Web應用程序提供了令人敬畏的新功能的完成,您終於準備好看到它的行動。您將新代碼添加到您的JavaScript基礎,構建發布候選者,並啟動您的瀏覽器,希望驚訝。然後……嗯……新功能可能運行良好,但是您的應用程序中的其他一些關鍵部分 - 在開發新版本時您沒有 touch
的部分 - 變得非常糟糕。現在,您面臨著在幾天工作中進行回溯的挑戰,以弄清楚如何打破現有代碼。快樂的日子絕對不在這裡。 >>這種情況比我想承認的要多。而且,如果您已經編碼了一段時間,那麼您也可能已經看到了它。但是,請考慮一下使這種情況如此痛苦的原因。這並不是因為我們的新代碼破壞了現有代碼;這是不可避免的。真正的痛苦是,花了很長時間才能注意到破裂。由於我們知道我們的應用程序正在起作用,因此有如此多的發展,因此該錯誤可能隱藏了大量代碼。而且,儘管它似乎有點像在草叢中尋找針頭,但我們別無選擇。 在本文中,我們將真正從JavaScript開發中消除這種情況。不再需要在數小時,數天或幾週的代碼中進行挖掘。我們將採用的原則是一個簡單的原則:在我們創建它後立即找到任何錯誤
。這是正確的;我們將建立一個開發環境和流程,當我們編寫引入錯誤的代碼時立即告訴我們。此外,一旦最初的開發完成,我們將付出的額外努力就不會浪費。在集成環境中,捕獲我們開發錯誤的相同測試代碼將完全重複使用。我們可以輕鬆地將測試納入我們的源代碼管理系統中,在錯誤進入我們的代碼庫之前阻止錯誤。 在以下四個部分中,我們將首先研究JavaScript測試環境所需的工具。然後,我們將考慮一個瑣碎的應用程序,該應用程序足夠簡單,可以理解,但具有實際生產Web應用程序中可能存在的所有功能。最後兩個部分展示了我們如何使用環境在開發過程中測試示例應用程序,並且在整合過程中初始開發完成後。
>我們已經確定我們的測試工具必須支持Web瀏覽器和Node.js環境,我們可以縮小選擇的範圍,以選擇核心測試框架。存在許多JavaScript測試框架,但大多數人傾向於瀏覽器測試。通常可以讓他們與node.js一起工作,但通常需要不高的黑客攻擊或調整。摩卡咖啡是一個不遭受此問題的框架,其合理地描述為:
Mocha最初是為Node.js開發的,它也很容易支持Web瀏覽器。通過使用Mocha作為我們的測試框架,我們可以編寫支持開發和集成而無需修改的測試。
sustert>,>期望, and 應該。代碼。在封面下,它們都是等效的。將測試從一種斷言樣式轉換為另一種主張風格很容易。斷言風格的主要區別在於它們的可讀性。主張樣式的選擇主要取決於您(或您的團隊)認為最可讀性的樣式,哪種風格會產生最可理解的測試。要查看差異,請考慮為以下代碼開發瑣碎的測試:>
>傳統的斷言測試可以寫為:<span>var sum = 2 + 2;</span>
該測試可以完成工作,但是除非您已經習慣了老式的單元測試,否則閱讀和解釋可能有些挑戰。替代斷言風格的使用期望:
assert<span>.equal(sum, 4, "sum should equal 4");</span>
大多數開發人員發現,與斷言風格的測試相比,預期的斷言更容易閱讀和理解。第三個替代方案應該使考試斷言更像是自然語言:
<span>expect(sum).to.equal(4);</span>
> Chai庫支持所有三種主張樣式。在本文中,我們應該堅持。
sum<span>.should.equal(4);</span>
>
>大多數Web應用程序,包括我們將在本文中考慮的瑣碎示例,依賴第三方庫和服務。在許多情況下,測試我們的代碼需要觀察甚至控制這些庫和服務。 Sinon.js庫提供了許多用於測試這些交互的工具。這樣的工具分為三個一般類:>我們測試工作台的最終工具是用於單元測試的開發環境。在我們的示例中,我們將使用Test’EM。 Test’em是一個方便的腳本集合,用於設置並運行連續的測試環境。如果我們選擇,我們可以自己編寫腳本並手動管理環境;但是,Toby Ho(Test’em的創建者)整理了一個很棒的軟件包,可以節省我們的麻煩。
要查看我們的測試環境,請考慮一個簡單的應用程序。儘管該應用程序包含了實際應用所需的所有功能,但該應用程序包含了其裸露的必需品。 (該應用程序的完整源代碼可在GitHub上找到。)
>>用戶可以看到他們的毒品列表,他們可以單擊一個複選框以切換任何todo的狀態。
todos數據庫>我們在其中放了一些測試數據後,表可能會看起來。
<span>var sum = 2 + 2;</span>
id
title我們的Web應用程序需要訪問此數據庫,因此我們將提供標準的REST接口。 API遵循Ruby慣例,但是任何服務器技術都可以輕鬆實現。特別是:
get api/todos/nnn返回todo的json表示,ID等於nnn。
>
在開發過程中進行測試<span>var sum = 2 + 2;</span>
>安裝工具
>我們需要的其他所有內容都可以作為節點軟件包可用。 Node軟件包管理器可以處理其安裝以及任何依賴項。
assert<span>.equal(sum, 4, "sum should equal 4");</span>
此示例的源代碼包括一個完整的項目結構,其中包含以下15個文件:
<span>expect(sum).to.equal(4);</span>
>最後,我們準備好編碼了。在命令外殼中,導航到我們項目的根文件夾並執行命令testem。 Test’em腳本將運行,清除終端窗口,並在右上方給我們一個URL。將該URL複製並粘貼到我們選擇的瀏覽器中,我們已經離開了。
>>
<span>var sum = 2 + 2;</span>
>本著真正的測試驅動開發的精神,我們將首先在測試/app-todos-test.js文件中編寫第一個測試用例。像任何好的Web應用程序一樣,我們希望最大程度地減少全球名稱空間污染。為此,我們將依靠一個全局變量doApp來包含我們的所有代碼。我們的第一個測試案例將確保存在全局名稱空間變量。
><span>var sum = 2 + 2;</span>
>
在測試塊中,我們通過測試的內容記錄了每個測試用例。這就是IT()函數的目的。讀取任何測試案例的方法是將描述()和()字符串組合到單個語句中。因此,我們的第一個測試案例是
應用程序為名稱space測試代碼本身在IT()塊內部。我們的測試案例是創建一個全局變量
assert<span>.equal(sum, 4, "sum should equal 4");</span>
終端窗口也會自動更新。
要進行測試,我們必須創建全局名稱空間變量。我們轉移到srcapp-todos.js文件並添加必要的代碼。
>我們保存文件後,請再次驗證“ EM再次彈出”。我們立即為測試案例獲得更新的結果。
<span>expect(sum).to.equal(4);</span>
>退後一會兒,考慮發生了什麼!每當我們更改測試代碼或應用程序時,Test`EM都會立即重新運行我們的整個測試套件。我們要做的就是將Test'Em的瀏覽器或終端窗口保持在屏幕的角落,並且在開發
>隨著我們的開發環境現已完全建立,我們可以開始開發應用程序。由於我們的應用程序顯示了招待員列表,因此最好為這些毒品創建一個模型。該模型將需要跟踪Todo的標題及其狀態。讓我們添加一個單元測試,該測試可以驗證我們可以使用合理默認值創建一個todo。
><span>var sum = 2 + 2;</span>
這些測試值得注意的幾個方面。
>使用第三方功能的存根
assert<span>.equal(sum, 4, "sum should equal 4");</span>
>在每個測試之前,我們還包括一些其他代碼,並且在每個測試後都添加了一部分代碼以執行。該額外的代碼管理Sinon存根,該函數有效地將代碼中的另一個函數取消。在我們的情況下,存根將this.todo的save()方法無效。有了存根,對該方法的呼叫實際上不會訪問後庫庫。相反,Sinon攔截了這些電話,並立即返回。這種行為很重要。如果我們試圖在單元測試環境中執行實際的骨幹保存()方法,則該調用將失敗,因為不會有數據庫或服務器API。
>存根後,我們的測試用例可以使用它來驗證模型的行為。在第一個測試案例中,我們立即將TODO的標題設置為新值。由於這更改了標題屬性,因此我們希望我們的模型更新其備份商店。為了檢查我們是否只驗證了該存根是被調用的。為了使我們的模型通過這些測試,我們可以尋找變更事件並做出適當的響應。
<span>var sum = 2 + 2;</span>
>
assert<span>.equal(sum, 4, "sum should equal 4");</span>
接下來,我們可以開發該列表項目視圖的詳細內容。例如,我們希望完整的列表項目看起來像以下內容。
<span>expect(sum).to.equal(4);</span>
對於我們的測試案例,我們可以利用jQuery從視圖的主要元素中提取單個元素。
sum<span>.should.equal(4);</span>
請注意,在上一個測試案例中,我們將模型的save()方法固定了。由於我們正在從其默認值中更改屬性,因此我們的模型將盡職盡責地將其持續到其備用商店。但是,在單元測試環境中,我們將沒有數據庫或服務器API。該存根取代了缺失的組件,並允許測試無錯誤進行。為了通過這些測試通過,我們必須在我們的視圖中添加一些其他代碼。
CREATE TABLE `todos` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary key for the table.', `title` varchar(256) NOT NULL DEFAULT '' COMMENT 'The text for the todo item.', `complete` bit(1) NOT NULL DEFAULT b'0' COMMENT 'Boolean indicating whether or not the item is complete.', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='To Do items.'
測試模型/視圖交互
<span><span><!DOCTYPE html></span> </span><span><span><span><html</span> lang<span>="en"</span>></span> </span> <span><span><span><head</span>></span> </span> <span><span><span><meta</span> charset<span>="utf-8"</span>></span> </span> <span><span><span><title</span>></span><span><span></title</span>></span> </span> <span><span><span></head</span>></span> </span> <span><span><span><body</span>></span> </span> <span><span><span><h1</span>></span>List of Todos<span><span></h1</span>></span> </span> <span><span><span><script</span> src<span>="lib/jquery-1.9.0.min.js"</span>></span><span><span></script</span>></span> </span> <span><span><span><script</span> src<span>="lib/underscore-min.js"</span>></span><span><span></script</span>></span> </span> <span><span><span><script</span> src<span>="lib/backbone-min.js"</span>></span><span><span></script</span>></span> </span> <span><span><span><script</span> src<span>="src/app-todos.js"</span>></span><span><span></script</span>></span> </span> <span><span><span><script</span>></span><span> </span></span><span><span> <span>$(function () { </span></span></span><span><span> <span>var todos = new todoApp<span>.Todos</span>(); </span></span></span><span><span> todos<span>.fetch(); </span></span></span><span><span> <span>var list = new todoApp<span>.TodosList</span>({collection: todos}); </span></span></span><span><span> <span>$("body").append(list.el); </span></span></span><span><span> <span>}) </span></span></span><span><span> </span><span><span></script</span>></span> </span> <span><span><span></body</span>></span> </span><span><span><span></html</span>></span></span>
。這是單元測試代碼。
請注意,我們再次將todo's save()方法固定。否則,當我們通過模擬單擊更改todo狀態時,骨干將嘗試更新不存在的備份商店。bash-3.2$ node --version v0.8.18 bash-3.2$ npm --version 1.2.2 bash-3.2$
對於測試用例本身,我們首先創建具有固定件ID的
<span>var sum = 2 + 2;</span>
在視圖中,我們想在元素上查看單擊事件,並為模型調用此方法。
assert<span>.equal(sum, 4, "sum should equal 4");</span>
但是,我們可以驗證我們對集合觀點的實施是否合適。我們希望該視圖呈現為無序列表(
<span>expect(sum).to.equal(4);</span>
視圖實現也很簡單。它跟踪集合中的任何添加並更新視圖。對於初始渲染(),它一次只會一次添加一個集合中的所有模型。
>sum<span>.should.equal(4);</span>
獎勵測試:驗證API
CREATE TABLE `todos` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary key for the table.', `title` varchar(256) NOT NULL DEFAULT '' COMMENT 'The text for the todo item.', `complete` bit(1) NOT NULL DEFAULT b'0' COMMENT 'Boolean indicating whether or not the item is complete.', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='To Do items.'
>秘密知道骨幹依賴於jQuery的$ .ajax()函數來實現REST API。我們可以通過固定該功能來攔截API相互作用。當我們啟動功能時,我們將要替代自己的響應。 存根的屈服方法為我們提供了這個機會。它告訴辛農(Sinon)在稱呼該存根時應採取什麼其他動作。這是一個完整的測試案例,可以驗證我們的收集使用REST API正確初始初始初始初始初始初始初始初始初始初始初始。
<span>var sum = 2 + 2;</span>
在集成期間進行測試
我們的代碼需要這些修改,因為Node.js處理全局變量的處理方式與Web瀏覽器不同。在Web瀏覽器中,默認情況下,JavaScript變量在範圍內是全局。另一方面,node.js默認情況下將變量限制在其本地模塊中。在那個環境中,我們的代碼將無法找到所需的第三方庫(jQuery,下劃線和骨幹。 。
>我們還需要調整測試代碼。測試腳本需要訪問自己的庫(jQuery,Chai,Sinon.js和Sinon-Chai)。此外,我們需要添加一些額外的內容來模擬Web瀏覽器的文檔對像模型(DOM)。回想一下,我們的點擊處理測試要求我們將“固定裝置”
<span>var sum = 2 + 2;</span>
>包裝這些語句測試的條件,以查看我們是否在Node.js環境中運行,而不是Web瀏覽器。在瀏覽器中,不需要額外的語句,因此我們可以安全地跳過它們。
>通過這些更改,我們可以從命令行執行完整的測試套件。只需導航到項目的根文件夾並執行命令摩卡咖啡即可。結果看起來很熟悉。>
結論
這是文章中使用的主要單元測試資源。
>命令行JavaScript執行環境:node.js
backbone.js與其他JavaScript框架一樣,支持單元測試以確保應用程序的質量。但是,由於其靈活性和簡單性,Backbone.js脫穎而出。它並不決定您的應用程序應如何構建,從而使開發人員可以自由設計自己的應用程序,因為他們認為合適。這種靈活性擴展到單元測試,使開發人員可以選擇其首選的測試工具和方法。此外,與其他框架相比,Backbone.js具有較小的佔地面積,使其用於單元測試更快,更有效。
>>我如何在backbone.js?
我可以在Backbone.js.js嗎?自動化單元測試在backbone.js中。自動化涉及建立連續集成(CI)系統,該系統每當對代碼進行更改時會自動運行測試。這樣可以確保更改引入的任何錯誤都會立即捕獲。有幾種CI工具,例如Jenkins,Travis CI和CircleCi,它們支持JavaScript,可用於在Backbone.js中自動化單元測試。
> 我可以在單元測試backbone.js嗎? >是的,您可以在單元測試骨幹鏈中使用模擬和存根。模擬和存根是模擬真實對象行為的假對象。它們用於隔離系統的其餘部分。這使得測試更加可靠,更容易編寫。有幾個可用的庫,例如sinon.js,它們提供了創建和管理模擬和存根的功能。 >我如何在backbone.js中調試失敗的單位測試?報告確定失敗的原因。大多數測試框架都提供詳細的錯誤消息,可以幫助您查明問題。您還可以使用chrome devtools或node.js debugger等調試工具逐步瀏覽您的代碼並檢查變量和函數調用。
>如何改善backbone.js中的單元測試的性能? Backbone.js中單元測試的性能涉及優化您的測試和測試環境。這包括編寫有效的測試,這些測試快速執行,並行運行測試以及使用快速的測試框架。您還可以使用分析工具在測試過程中識別慢速測試和瓶頸。
>
以上是單元測試骨幹。JS應用程序的詳細內容。更多資訊請關注PHP中文網其他相關文章!