摘要:在互聯(lián)網(wǎng)時代,隨著業(yè)務(wù)增長,前端需求激增,軟件產(chǎn)品功能迭代加快,前端代碼質(zhì)量越來越受到重視,如何在有限時間內(nèi)保證前端代碼質(zhì)量。就此問題將介紹前端JavaScript代碼覆蓋率工具Istanbul,分析lstanbul的四種代碼覆蓋率測量指標(biāo),并通過具體實(shí)例闡述lstanbul在前端單元測試中的應(yīng)用。應(yīng)用結(jié)果表明lstanbul能快速定位未被測試覆蓋的代碼,以此完善測試用例,提升軟件產(chǎn)品質(zhì)量。
關(guān)鍵詞:軟件測試;單元測試;代碼覆蓋率;lstanbul
中圖分類號:TP319 文獻(xiàn)標(biāo)識碼:A
文章編號:1009-3044(2020)08-0059-03
1 背景
軟件測試是軟件工程中重要一環(huán),用于驗(yàn)證產(chǎn)品代碼按照預(yù)期工作,是保障軟件產(chǎn)品質(zhì)量的重要手段。其中,單元測試是對軟件最小執(zhí)行單元的測試活動,能盡早發(fā)現(xiàn)軟件缺陷,是軟件測試的基礎(chǔ)。以往單元測試只針對服務(wù)器端語言,隨著web業(yè)務(wù)的發(fā)展,前端代碼日趨復(fù)雜,使得對JavaScript進(jìn)行單元測試尤為重要。
代碼覆蓋率是軟件測試的度量指標(biāo),反映測試用例對被測軟件代碼的覆蓋程度,量化測試工作。通過代碼覆蓋率測試能及時確認(rèn)未被測試用例執(zhí)行的代碼,提前發(fā)現(xiàn)代碼邏輯分支不合理之處,提升產(chǎn)品代碼的可靠性和穩(wěn)定性。
2 Istanbul介紹
Istanbul是前端JavaScript常用的代碼覆蓋率測試工具,以土耳其名城伊斯坦布爾命名,它可以靜態(tài)直接統(tǒng)計(jì)JavaScript文件,也可以結(jié)合測試框架在單元測試中對JavaScript文件進(jìn)行覆蓋率統(tǒng)計(jì)。
Istanbul提供了四種代碼覆蓋率測量指標(biāo)。語句覆蓋率(statement coverage)統(tǒng)計(jì)代碼中所有可執(zhí)行語句的執(zhí)行率。分支覆蓋率(branch coverage)統(tǒng)計(jì)代碼中所有分支的執(zhí)行率,即判斷的取真分支和取假分支是否都被執(zhí)行了。函數(shù)覆蓋率(func-tion coverage)統(tǒng)計(jì)代碼中所有函數(shù)的被調(diào)用率。行覆蓋率(linecoverage)統(tǒng)計(jì)代碼中所有有效代碼行的執(zhí)行率,其與語句覆蓋率類似,在代碼規(guī)范的情況下,行覆蓋率和語句覆蓋率應(yīng)該是一致的。以上四種測量指標(biāo)是Istanbul的輸出結(jié)果,每個指標(biāo)均列出了覆蓋的數(shù)量和比例,其中分支覆蓋率能深入發(fā)現(xiàn)代碼邏輯中的缺陷,是四種覆蓋中最強(qiáng)的覆蓋。
運(yùn)行npm install istanbul-g將Istanbul安裝為全局模塊,安裝成功后運(yùn)行istanbul help可查看其幫助信息。
3 Istanbul收集覆蓋率信息
下面來看一個使用Istanbul收集覆蓋率信息的簡單實(shí)例,測試文件simple.js見圖1。
運(yùn)行istanbul cover simple.js,得到4個覆蓋率測量指標(biāo)結(jié)果見圖2。
以上結(jié)果顯示,simple.js有4個語句,執(zhí)行了3個,因此語句覆蓋率為75%;有2個分支,執(zhí)行了1個,因此分支覆蓋率為50%;有0個函數(shù),調(diào)用了0個,因此函數(shù)覆蓋率為100%;有4行代碼,執(zhí)行了3行,因此行覆蓋率為75%。
Istanbul會在coverage/lcov-report目錄下生成HTML報(bào)告,可直觀查看到覆蓋率詳細(xì)信息,定位沒有被覆蓋到的代碼。打開coverage/lcov-report/index.html文件,頁面中展示各文件夾下文件的代碼覆蓋率見圖3。
點(diǎn)擊相應(yīng)文件夾,可見該文件的代碼覆蓋率統(tǒng)計(jì)情況見圖4。
綠色部分表示該行代碼被完整執(zhí)行,紅色部分表示該行代碼沒有被執(zhí)行,即未覆蓋a= false的情況。
4 Istanbul代碼覆蓋率標(biāo)準(zhǔn)檢查
Istanbul除了收集覆蓋率信息,還可根據(jù)測試要求設(shè)定滿意的代碼覆蓋率標(biāo)準(zhǔn),來檢查覆蓋率是否達(dá)到設(shè)定的指標(biāo),如果未達(dá)標(biāo)則打印錯誤信息。
4.1 百分比標(biāo)準(zhǔn)
對測試文件simple.js運(yùn)行istanbul check-coverage -state-ment 85
該命令設(shè)置語句覆蓋率標(biāo)準(zhǔn)為85%,運(yùn)行結(jié)果見圖6。
因測試文件simple.js的語句覆蓋率為75%,未達(dá)到設(shè)定的語句覆蓋率標(biāo)準(zhǔn)85%,故報(bào)錯提示語句覆蓋率未達(dá)標(biāo)。
4.2 絕對值標(biāo)準(zhǔn)
對測試文件simple.JS運(yùn)行istanbul check-coverage -branch一1
該命令設(shè)置允許有1個分支未被覆蓋,運(yùn)行結(jié)果見圖7。
因測試文件simple.js有1個分支未被執(zhí)行,符合設(shè)定的分支覆蓋率標(biāo)準(zhǔn),故通過了覆蓋率測試,運(yùn)行結(jié)果無報(bào)錯。
4.3 百分比標(biāo)準(zhǔn)和絕對值標(biāo)準(zhǔn)結(jié)合使用
百分比標(biāo)準(zhǔn)和絕對值標(biāo)準(zhǔn)可結(jié)合使用,對測試文件simple.js運(yùn)行istanbul check-coverage -statement 85 -branch—l -functionl00 -line一1
該命令共設(shè)置了4個覆蓋率標(biāo)準(zhǔn):語句覆蓋率標(biāo)準(zhǔn)為85%,允許1個分支未被執(zhí)行,函數(shù)覆蓋率標(biāo)準(zhǔn)為100%,允許1行代碼未被執(zhí)行。這4個標(biāo)準(zhǔn)間是“與”的關(guān)系,即只要1個標(biāo)準(zhǔn)未達(dá)標(biāo),則報(bào)錯。運(yùn)行結(jié)果見圖8。
因測試文件simple.js語句覆蓋率為75%,未達(dá)到設(shè)定的語句覆蓋率標(biāo)準(zhǔn)85%,故報(bào)錯提示語句覆蓋率未達(dá)標(biāo)。
5 Istanbul結(jié)合Mocha測試框架
測試框架提供腳本運(yùn)行的環(huán)境,是運(yùn)行測試的工具。實(shí)際應(yīng)用中,Istanbul總是與測試框架結(jié)合使用,Mocha是一款流行的JavaScript單元測試框架,適用于瀏覽器和Node.js環(huán)境。Mo-cha用describe塊和it塊來進(jìn)行測試用例分組,測試腳本中包含一個或多個describe塊,每個describe塊包含一個或多個it塊。describe為測試套件testsuite,表示一組相關(guān)的測試,該函數(shù)包含兩個參數(shù),第一個參數(shù)是測試套件名稱(在測試報(bào)告中顯示的描述),第二個參數(shù)是實(shí)際執(zhí)行的函數(shù)。it塊為單個測試用例testcase,表示一個獨(dú)立的測試,它是真正執(zhí)行的部分,該函數(shù)包含兩個參數(shù),第一個參數(shù)是測試用例名稱(在測試報(bào)告中顯示的描述),第二個參數(shù)是實(shí)際執(zhí)行的函數(shù)。運(yùn)行npm install mo-cha—g將Mocha安裝為全局模塊,安裝成功后運(yùn)行mocha -help可查看其幫助信息。
斷言可判斷源代碼的執(zhí)行結(jié)果與預(yù)期結(jié)果是否一致,若不一致則拋出錯誤。Mocha不提供斷言,可搭配Chai使用。Chai是流行的JavaScript測試斷言庫,適用于Node.JS和瀏覽器的行為驅(qū)動測試以及測試驅(qū)動測試,能搭配測試框架一起使用。運(yùn)行npm install chai—g將Chai安裝為全局模塊。
以下為判斷輸入是否為數(shù)字的腳本文件。定義srtP為正則表達(dá)式,使用test0方法,將輸入值與srtP進(jìn)行匹配,若不匹配說明輸入包含非數(shù)字,返回false。若匹配,說明輸入均為數(shù)字,返回true。腳本文件my.Js見圖9。
修改my.Js文件,把模塊中希望被外界訪問的內(nèi)容定義到exports對象中,以便在測試腳本中使用(require引用該模塊),修改后文件isNum.js見圖10。
編寫單元測試腳本testNum.js見圖11,測試用例包含1個測試單元,若輸人數(shù)字4則得到true。將測試腳本放在test目錄下。
運(yùn)行istanbul cover node—global/ node—modules/ mocha/ bin/_mocha,進(jìn)行代碼覆蓋率檢查,結(jié)果見圖12。結(jié)果顯示1個測試用例成功通過,函數(shù)覆蓋率為100%,但語句覆蓋率、分支覆蓋率、行覆蓋率未達(dá)到100%。
查看coverage/lcov-report下HTML報(bào)告見圖13,可知num為false的分支未覆蓋,需添加新的測試用例來覆蓋缺失的測試場景。
完善測試用例,測試腳本testNum.js見圖14,測試用例分為2個測試單元,若輸入數(shù)字4則得到true,若輸入字母d則得到false。
再運(yùn)行istanbul cover node_global/node_modules/mocha/bin/_mocha進(jìn)行代碼覆蓋率檢查,結(jié)果見圖15。結(jié)果顯示2個測試用例都成功通過了,語句覆蓋率、分支覆蓋率、函數(shù)覆蓋率、行覆蓋率均為100%。
查看coverage/lcov-report下HTML報(bào)告見圖16.顯示已覆蓋num為false的分支。
6 結(jié)束語
代碼覆蓋率測試能發(fā)現(xiàn)未被覆蓋的代碼,這部分代碼出現(xiàn)不可預(yù)知行為的機(jī)率較大,有存在問題的風(fēng)險(xiǎn),影響代碼質(zhì)量,應(yīng)引起足夠重視。Istanbul能從語句、分支、函數(shù)、行四種測量維度提供覆蓋率信息,幫助迅速定位未被執(zhí)行的代碼,指導(dǎo)有針對性地補(bǔ)充測試用例,盡可能地發(fā)現(xiàn)更多潛在代碼缺陷,提高代碼質(zhì)量,為用戶提供穩(wěn)定可靠的軟件產(chǎn)品。
參考文獻(xiàn):
[1]陳衛(wèi)俊,趙璨,周磊,互聯(lián)網(wǎng)單元測試及實(shí)踐[M].北京:電子工業(yè)出版社,2008.
[2]王飛,向螈.C++Test在核電數(shù)據(jù)庫軟件單元測試中的應(yīng)用研究[J].電腦知識與技術(shù),2019,15(12):1-3.
[3]褚悅,代碼覆蓋率驅(qū)動的測試用例管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[D].西安:西安電子科技大學(xué),2017.
[4]尤嘉.Node.js進(jìn)階之路[Ml.北京:清華大學(xué)出版社,2017.
【通聯(lián)編輯:謝媛媛】
收稿日期:2020-01-25
基金項(xiàng)目:2017年國家重點(diǎn)研發(fā)計(jì)劃(項(xiàng)目編號:2017YFB0802300)
作者簡介:史蓓娜(1986-),女,江蘇常州人,研究實(shí)習(xí)員,學(xué)士,研究方向?yàn)橛?jì)算機(jī)應(yīng)用。