您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關編寫可測試的JavaScript代碼有哪些,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
一、可測試的JavaScript
A.現有技術
1.敏捷開發
①使用敏捷開發,并不一定意味著應用程序完成得更快且質量更高,敏捷開發最大的優勢是它處理需求變更的方式。
②快速迭代和持續交互可以加快高質量軟件的交付。
2.測試驅動開發
在編寫代碼之前先編寫測試,這些測試提供了必須遵循預期功能的代碼,編寫測試失敗后,接著開始編寫代碼,以便確保測試能夠通過。保持測試領先于開發,永遠不會有未被測試的代碼。
3.行為驅動開發
它為開發人員和非開發人員提供了一種能用語言,用于描述正確的應用程序行為和模塊行為,該通用語言是日常語言。
B.代碼是讓人用的
1.我們編寫的代碼不是讓電腦用的,而是讓人用的
2.為何要編寫可測試的代碼
可測試的代碼更加容易測試,意味著它更加容易維護,易維護則意味著它有讓人(包括自己)更加容易理解 ,更加容易維護,從而又使得測試變得更加容易
3.如果沒有可測試的、可維護的以及可理解的代碼,那它就是垃圾
4.什么是可測試的代碼
什么是可測試:短小但也不太復雜的代碼、完整的注釋,以及檢耦合。
什么是可維護:可以存在于一個完整的產品周期:產品從一個人轉到另外一個人手里時,不需要部分或全部重寫
什么是可理解:簡單的、小型的且有注釋的代碼更加容易理解
5.如何編寫可測試的代碼:編寫短小、最小依賴和最低復雜度的可隔離的代碼塊
二、復雜度
A.代碼大小
可以讓函數保持最小代碼量的一個方法讓命令(Command)和查詢(Query)保持分離。命令函數表示做什么(do something),而查詢函數則表示返回什么(return something)。也就是說,命令表示setter,查詢表示getter。命令函數使用模(mock)進行測試,而查詢函數使用樁(stub)進行測試。讓這些概念保持分離,并提高可測試性,通過確保讀寫分離,可以實現良好的可伸縮性。
B.JSLint
http://www.jslint.com/
C.圈復雜度
1.圈復雜度是表示代碼中獨立現行路徑的數量。換句話說,它是為錘煉所有的代碼,需編寫的單元測試的最小數量。
2.生成代碼的圈復雜度可以使用像jsmeter這樣簡單的命令行工具
3.為了實現合理性和可維護性,保持較低的圈復雜度是一個好辦法
4.圈復雜度高的代碼通常是由很多if/then/else語句造成的,最簡單的修復是將方法分解成更小的方法
5.使用jscheckstyle來計算圈復雜度
D.重用
1.減小代碼大小的最好辦法是減少編寫的代碼量。其理論是使用其他人維護的可用于生產環境的第三方(外部或內部的代碼),這樣就可以減少一大筆代碼維護成本。
2.典型的應用程序由20%的通用組件和高達65%與具體領域有關的可重用組件構成。而程序的其余部分則是由具體應用系統相關的定制化代碼和一些地方所使用到的實用程序構成。
①程序特定:我們自己編寫的代碼
②領域特定:在程序中使用的第三方模塊
③領域獨立:類似YUI這樣的框架或Node.js
3.如果發現代碼被編寫了兩遍,那就是時候將其提取到函數中了。
E.扇出
1.扇出(Fan-out)測量函數直接或間接依賴的模塊或對象的數量。
2.扇出:
過程A的扇出是表示過程A的內部流程數量與過程A所更新的數據結構數量之和。
在該定義中,如下任意操作都算作一個內部流程(以方法B和C為例):
①如果A調用B;
②如果B調用A,并且A返回一個B隨后 可以利用的值;
③如果C調用A和B,且A的返回值傳遞給B。
所以,將函數A所有的內部流程,加上A所更新的全局結構(相對于A外部),產生的數字就是函數A的扇出。
3.對于所有的函數 ,計算該扇出值和該值所對應的扇入值,將兩數相乘,并進行平方計算,其結果數字 就是一個函數 的復雜度。(fan_in * fan_out)2
4.對于高復雜度的代碼:
高扇入和扇出的代碼,可能表示一個函數正在嘗試做太多事情,應該避免
高扇入和扇出,可以判定出系統的壓力點,維護這些函數將會非常困難,因為它們關聯太多的系統其它部分
它們不夠精細,
5.高扇出會帶來的問題:代碼更復雜、更難以理解 ,所有更難以測試;而且測試過程中,每個直接依賴必須要被模擬(mock或stub),所以會增加創建測試的復雜性;并且扇出象征著著緊耦合,會使函數和模塊過于脆弱。
F.扇入
1.過程A的扇入是過程A的內部流程數量與欲從過程A中獲取信息的數據結構數量之和。
G.耦合:六級耦合
1.內容耦合:內容耦合是最緊的耦合形式,包括在外部對象上調用方法或函數,或通過修改外部對象的屬性直接改變對象狀態。
2.公共耦合:如果兩個對象都共享另外一個全局變量,則這兩個對象就有公共耦合了。
3.控制耦合:該耦合基于標記或參數設置來控制外部對象。
4.印記耦合:通過向外部對象傳遞一個記錄,而只使用該記錄的一部分
5.數據耦合:發生在一個對象傳遞給另一個對象消息數據,而沒有傳遞控制外部對象的參數時。
6.無耦合:任意兩個對象之間的絕對零耦合。
*雖然不是正式耦合的一部分,實例化一個非單例全局對象的行為也是一種非常緊密的耦合,其耦合程度接近于內容耦合,但比公共耦合緊密。
H.耦合性度量
1.代碼檢查和代碼審查是查找代碼耦合的一個非常好的方法,而不是依靠工具來發現耦合性度量
I.依賴注入
1.注入和模擬是松散的關系,注入負責構造對象,并將對象注入到代碼中;而模擬是在調用的時候替換對象或方法以便于測試。工廠化依賴,或手動將依賴注入到構造函數或方法調用中,有助于減少代碼的復雜性,但也會增加一些開銷:如果一個對象的依賴項需要注入,而另外一個對象此時則負責構建該對象。
2.依賴注入器可以為代碼構建和注入完全成型的對象。
J.注釋
1.對于可測試的JavaScript,所有即將要測試的函數或方法前面都有相應的注釋。根據這些注釋,我們(或其他人)可以知道如何進行測試以及測試什么內容。
2.YUIDoc和JSDoc可以將所有的注釋轉換為HTML。
3.Docco/Rocco,從代碼中解析出Markdown風格的注釋。
三、基于事件的架構
A.基于事件編程的好處
1.從核心上看,所有的應用程序都與消息傳遞有關。可能會發生緊耦合,因為代碼需要另一個對象的引用 ,以便可以給對象發送消息或接收消息。
2.全局的依賴關系是很危險的:系統的任何部分接觸它們,都使得BUG很難跟蹤;如果我們有同名或類似的局部變量,一不小心就會改變這些全局依賴;由于無處不在的特性,也會導致數據封裝出錯,使得調試非常困難。JS全局變量的聲明和使用很簡單,并且宿主環境通常提供了多個全局變量、全局函數和全局對象。這意味著,將變量保存到全局作用域內必須要小心,因為全局作用域內已經有很多全局對象了。
3.基于事件的編程都可以歸結為兩個主要部分:調用和返回。將調用轉換為參數化的事件,并返回一個參數化的回調。
B.事件集線器
1.事件背后的思想很簡單:將方法注冊到事件中心,指定其能夠處理的某些事件。方法利用停線器獨立的中央處理器,負責事件請求,并等待響應。
2.該架構發揮了JS函數的優勢,鼓勵使用最小依賴項的小型耦合代碼。鼓勵開發人員編寫使用最小依賴項的小塊代碼,使用事件而不是方法調用,可以極大地提高可測試性和可維護性。
3.基于事件的架構幫助執行了MVC所倡導的關注點分離以及模塊化,區別在于,基于事件的架構模型被打亂、消除或分離,這取決于我們如何看待這些模型。基于事件架構的數據并不是存儲在對象中。沒有任何修飾符,所有的內容都是私有的,與“外部”世界唯一的溝通就是通過基于事件的API。
C.測試基于事件的架構
1.基于事件架構的本質:注冊事件監聽,并且沒有(或很少)對象被實例化
D.基于事件架構的說明
1.可伸縮性:事件集線器創造了超級單一故障點,如果集線器出現了故障,應該程序就宕機了
2.廣播:使用廣播將很多事件廣播給所有的客戶端可能會帶來很多通信流量
3.運行時檢測:編譯器沒有辦法檢查字符串形式的事件名稱的拼寫錯誤,強烈建議對事件名稱使用枚舉或散列,而不是在輸入的時候一遍一遍檢查
4.安全性
5.狀態:通常是由Web服務器通過會話cookie,從Web服務器提供給業務模塊的
四、單元測試
A.單元測試框架
1.測試框架最重要的部分是將測試聚合到測試套件和測試用例中。測試套件和測試用例是分散在很多文件中的,并且每個測試文件通常只包含單個模塊的測試。最好的辦法是將一個模塊的所有測試都歸類到一個單獨的測試套件中。
2.斷言是將期望值和實際值進行比較的實際應用。
B.開始編寫測試
1.YUI test
https://github.com/zhangyue0503/html5js/blob/master/testablejs/1.html
C.編寫好的單元測試
1.怎樣編寫一個好的單元測試?代碼覆蓋率。
2.隔離:單元測試應該只加載 所需測試的最小代碼進行測試。任何額外的代碼都可能會影響測試或被測試代碼,而且還會產生問題。
3.范圍:必須很小,一個完全隔離的方法可以讓測試的范圍盡可能地小。
4.在編碼之前,利用測試驅動開發先編寫單元測試,并不能避免函數所需要的注釋。如果先編寫測試用例,也可以用于規范函數 (或被測試代碼)功能
5.正向測試:按正確的數據測試,首先要編寫的單元測試,因為在構建負向測試和邊界測試之前 ,它們提供了基本的預期功能。
6.負向測試:傳入非期望的函數或該函數不想要的參數進行測試,確保被測試的函數能夠處理它們。負向測試找到的BUG通常是難以對付的BUG。
7.代碼覆蓋率:是指一種度量方法,通常是指執行代碼與非執行代碼行數之間的百分比,是有效單元測試的另一個關鍵部分
D.真實場景測試
1.單元測試者可以利用模(mock)和樁(stub)提取依賴關系,mock用于命令,而sub用于查找
2.測試替身:描述的是使用sub或mock模擬依賴對象進行測試。
E.運行客戶端JavaScript單元測試
1.PhantomJS
2.Selenium
F.運行服務器端JavaScript單元測試
1.jasmine
五、代碼覆蓋率
為代碼覆蓋率信息構建相應的JS文件,部署或練習這些文件,并把覆蓋率結果推送并持久化到一個本地文件中,也可以將不同測試的覆蓋率結果組合在一起,生成漂亮的html輸出,或者僅僅為上游工具或報告獲取相應的覆蓋率數字和百分比
A.覆蓋率基礎理論
1.理論上講,“覆蓋”的代碼行數越多,測試就越完整,然而,代碼覆蓋率和測試完整性之間的聯系是很脆弱的。
B.代碼覆蓋率數據
1.代碼覆蓋率數據分為兩部分,代碼行的覆蓋率和函數的覆蓋率。
六、集成測試、性能測試、負載測試
A.集成測試
1.Selenium:通常需要在瀏覽器的同一個沙盒上運行大量的java代碼以便運行測試,以及一個用于控制遠程瀏覽器的客戶端API,可以使用各種語言編寫Selenium小夜曲。
2.CasperJS:提供了與Selenium類似的功能,但完全不限制環境。
B.性能測試
1.HAR文件:可用于查看的json格式對象,可以使用很多工具對其進行查看,要監控web應用程序的性能,需要生成應用程序概要的HAR文件,然后檢查數據并發現問題。
C.負載測試
1.nodeload,(Apache Bench的node.js版本)
七、調試
A.瀏覽器內調試
1.firebug
2.chrome
B.Node.js調試
1.命令行調試器
node debug myscript.js
C.遠程調試
1.chrome遠程調試
2.PhantomJS
3.firefox遠程調試:Crossfire擴展
D.移動調試
1.原生支持:Android4以及ios6以后
E.生產環境調試
1.源映像文件
八、自動化
A.自動化什么內容
自動化一切,任何不止一次操作的內容都應該自動化。
B.何時進行自動化
三個時機:編碼階段、構建階段、部署階段
關于編寫可測試的JavaScript代碼有哪些就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。