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