日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JavaScript覆盖率统计实现

發布時間:2023/11/30 javascript 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript覆盖率统计实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

主要需求

1、 支持browser & nodejs

由于javascript既能夠在瀏覽器環境執行,也能夠在nodejs環境執行,因此須要能夠統計兩種環境下單元測試的覆蓋率情況。

2、 透明、無縫

用戶寫單元測試用例的時候,不須要為了支持覆蓋率統計多寫代碼,之前寫的用例無需改動就能夠直接統計覆蓋率情況。

原理

javascript覆蓋率的相關文章比較少。以下的圖是通過閱讀開源javascript覆蓋率工具istanbul及開源測試框架Karma的覆蓋率插件karma-coverage得出的。

javascript覆蓋率統計的核心思想是,在源碼對應的位置注入統計代碼,當代碼執行之后,依據統計代碼統計的數據確定程序執行的路徑,終于生成覆蓋率統計報告。



1. 轉換(instrument)

  • 使用開源工具Esprima對源碼進行語法分析生成語法樹
  • 在語法樹對應的位置注入統計代碼。在程序運行到這個位置的時候對對應的全局變量賦值,確保運行之后可以依據全局變量知道代碼的運行流程
  • 使用開源工具Escodegen依據注入之后的語法樹生成對應的javascript代碼,即轉換之后的代碼(instrumented code)

注:這里進行語法分析的優點是,針對書寫不規范的代碼(比方一行多個語句),依舊可以非常好統計出分支覆蓋和組合覆蓋等信息。

2. 運行(run)

這一步須要先加載轉換后的代碼:

  • nodejs:直接通過對require語句進行hook來無縫實現,后面會具體介紹
  • 瀏覽器環境:須要將轉換后的代碼傳給瀏覽器。假設是karma之類的帶server的測試框架,須要通過socket傳輸至瀏覽量器,運行完之后再將包括覆蓋率信息的運行結果傳回server。生成測試報告

然后運行單元測試。產生的統計信息會掛在全局變量this以下。

對于瀏覽器環境,this就是window,而對于nodejs環境this就是global。

3. 生成報告(report)

這一步會依據全局標量中的覆蓋率信息生成特定格式的報告,如html、lcov、cobertura、teamcity等。

一個樣例

//source code function abs(num){if(abs > 0)return num;elsereturn -num; } //instrumented code var __cov_iypKC$dWI6uJFmvxThycaA = (Function('return this'))(); if (!__cov_iypKC$dWI6uJFmvxThycaA.__coverage__) { __cov_iypKC$dWI6uJFmvxThycaA.__coverage__ = {}; } __cov_iypKC$dWI6uJFmvxThycaA = __cov_iypKC$dWI6uJFmvxThycaA.__coverage__; if (!(__cov_iypKC$dWI6uJFmvxThycaA['/Users/lonfee88/Codes/testframe/coverage-jasmine-istanbul-karma/abs.js'])) {__cov_iypKC$dWI6uJFmvxThycaA['/Users/lonfee88/Codes/testframe/coverage-jasmine-istanbul-karma/abs.js'] = {"path":"/Users/lonfee88/Codes/testframe/coverage-jasmine-istanbul-karma/abs.js","s":{"1":1,"2":0,"3":0,"4":0},"b":{"1":[0,0]},"f":{"1":0},"fnMap":{"1":{"name":"abs","line":1,"loc":{"start":{"line":1,"column":-15},"end":{"line":1,"column":17}}}},"statementMap":{"1":{"start":{"line":1,"column":-15},"end":{"line":6,"column":1}},"2":{"start":{"line":2,"column":1},"end":{"line":5,"column":14}},"3":{"start":{"line":3,"column":2},"end":{"line":3,"column":13}},"4":{"start":{"line":5,"column":2},"end":{"line":5,"column":14}}},"branchMap":{"1":{"line":2,"type":"if","locations":[{"start":{"line":2,"column":1},"end":{"line":2,"column":1}},{"start":{"line":2,"column":1},"end":{"line":2,"column":1}}]}}}; } __cov_iypKC$dWI6uJFmvxThycaA = __cov_iypKC$dWI6uJFmvxThycaA['/Users/lonfee88/Codes/testframe/coverage-jasmine-istanbul-karma/abs.js']; function abs(num){__cov_iypKC$dWI6uJFmvxThycaA.f['1']++;__cov_iypKC$dWI6uJFmvxThycaA.s['2']++;if(abs>0){__cov_iypKC$dWI6uJFmvxThycaA.b['1'][0]++;__cov_iypKC$dWI6uJFmvxThycaA.s['3']++;return num;}else{__cov_iypKC$dWI6uJFmvxThycaA.b['1'][1]++;__cov_iypKC$dWI6uJFmvxThycaA.s['4']++;return-num;}}

node.js集成覆蓋率

通過hook能夠直接無縫的載入轉換后的代碼。能夠對以下兩種語句進行hook:

  • require
  • vm.createScript

對require進行hook的代碼是通過對Module._extensions['.js']進行賦值實現的:

function hookRequire(matcher, transformer, options) {options = options || {};var fn = transformFn(matcher, transformer, options.verbose),postLoadHook = options.postLoadHook &&typeof options.postLoadHook === 'function' ? options.postLoadHook : null;Module._extensions['.js'] = function (module, filename) {var ret = fn(fs.readFileSync(filename, 'utf8'), filename);if (ret.changed) {//加載instrument之后的代碼并執行module._compile(ret.code, filename);} else {//加載原來的代碼并執行originalLoader(module, filename);}if (postLoadHook) {postLoadHook(filename);}}; }

hook使覆蓋率的集成變得簡單。甚至不須要寫代碼,比方Mocha的覆蓋率集成,僅僅須要改用例如以下的調用方式就可以:

istanbul cover _mocha -- -R spec test/spec

瀏覽器集成覆蓋率

瀏覽器集成覆蓋率就略微麻煩一點。好在istanbul提供了API:

  • 轉換代碼(調用istanbul的Instrumenter接口)
  • 將instrumented code發送到瀏覽器(自己實現)
  • 將包括覆蓋率信息的運行結果發回server(自己實現)
  • 依據返回的覆蓋率信息生成覆蓋率報告(調用istanbul的Reporter接口)
  • 轉載于:https://www.cnblogs.com/jzdwajue/p/6900462.html

    總結

    以上是生活随笔為你收集整理的JavaScript覆盖率统计实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。