亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

深入了解JavaScript代碼覆蓋

2024-05-06 16:52:05
字體:
來源:轉載
供稿:網友

它為什么是有用的? 

作為一名JavaScript開發者,你可能經常發現自己處于代碼覆蓋可能有用的情景。例如:

  • 對測試套件的質量感興趣? 重構一個大型的遺留項目? 代碼覆蓋可以準確顯示代碼庫中已覆蓋了哪些部分。
  • 想快速了解是否覆蓋了代碼庫的特定部分? 代碼覆蓋可以顯示有關應用程序的哪些部分已被執行的實時信息,而不是使用console.log進行printf-風格的調試或手動執行代碼。
  • 或者你可能正在優化速度,并想知道要關注哪些點? 執行次數可以指出關鍵函數和循環。

JavaScript在V8中的代碼覆蓋

今年早些時候,我們在V8上添加了對JavaScript代碼覆蓋的原生支持。5.9版本中的初始發布提供了函數粒度(顯示已執行的函數)的覆蓋范圍,后來擴展為支持在v6.2中的塊粒度覆蓋(同樣的,僅對于單獨表達式有效)。

JavaScript,代碼覆蓋

函數粒度(左側)和塊粒度(右側)

對JavaScript開發者

目前訪問覆蓋信息有兩種主要的方式。對于JavaScript開發者,Chrome DevTools的Coverage tab給出了JS (和CSS)覆蓋率并在源碼面板中指出了無用代碼。

JavaScript,代碼覆蓋

塊覆蓋coverage 在DevTools Coverage 面板中的塊覆蓋。覆蓋的行使用綠色標注,未覆蓋的行則使用紅色。

JavaScript,代碼覆蓋

基于V8覆蓋數據的Istanbul.js報告

給嵌入式

嵌入式及框架作者可以通過直接hook到Inspector API上獲得更大的靈活性。V8提供兩種不同的覆蓋模式:

1.盡力覆蓋模式下收集覆蓋信息,確保在運行時對性能的影響最小,但可能會丟失已被垃圾回收(GC)函數的數據。

2.精確覆蓋確保不會因為GC而丟失任何數據,用戶可以選擇接收執行計數而不是二進制覆蓋信息;但性能可能會受此額外開銷的影響(有關詳細信息,請參閱下一節)。精準覆蓋可以按函數或塊粒度收集信息。

精準覆蓋的Inspector API如下:

  • Profiler.startPreciseCoverage(callCount, detailed) 使能覆蓋信息收集,可選調用次數(vs.二進制覆蓋)以及塊粒度(vs. 函數粒度);
  • Profiler.takePreciseCoverage() 返回已收集的覆蓋信息,其中包含源碼范圍列表以及相關的執行次數;
  • Profiler.stopPreciseCoverage() 禁用收集并釋放相關數據結構。

Inspector協議間的通信可能如下所示:

// The embedder directs V8 to begin collecting precise coverage.{ "id": 26, "method": "Profiler.startPreciseCoverage","params": { "callCount": false, "detailed": true }}// Embedder requests coverage data (delta since last request).{ "id": 32, "method":"Profiler.takePreciseCoverage" }// The reply contains collection of nested source ranges.{ "id": 32, "result": { "result": [{"functions": [{"functionName": "fib","isBlockCoverage": true, // Block granularity."ranges": [ // An array of nested ranges.{"startOffset": 50, // Byte offset, inclusive."endOffset": 224, // Byte offset, exclusive."count": 1}, {"startOffset": 97,"endOffset": 107,"count": 0}, {"startOffset": 134,"endOffset": 144,"count": 0}, {"startOffset": 192,"endOffset": 223,"count": 0},]},"scriptId": "199","url": "file:///coverage-fib.html"}]}}// Finally, the embedder directs V8 to end collection and// free related data structures.{"id":37,"method":"Profiler.stopPreciseCoverage"}

同理,盡力覆蓋可以使用 Profiler.getBestEffortCoverage() 。

幕后細節

如上一節所述,V8支持兩種主要的代碼覆蓋模式:盡力和精確覆蓋。欲了解他們實現概述,請繼續閱讀。

盡力覆蓋 

盡力和精確覆蓋模式都大量重用其它的V8機制,其中首數被稱為調用計數器的機制。每次通過V8的Ignition解釋器調用函數時,我們都會在函數的反饋向量上增加其調用計數器。隨著函數后來變得愈加頻繁并通過優化編譯器做了提升,這個計數器用于幫助輔助關于內聯函數的內聯決策;現在,我們也依靠它報告代碼覆蓋情況。

第二種重用機制確立了函數的源碼范圍。報告代碼覆蓋時,調用計數需要與源文件中的相關范圍作關聯。例如,在下面的示例中,我們不僅需要報告函數f已經執行了一次,還包含f的源碼范圍從第1行開始到第3行結束。

 

function f() {console.log('Hello World');}f();

又一次我們是幸運的,我們能夠重用 V8 中的現有信息。由于 Function.prototype.toString 需要知道函數在原文件中的位置以提取適當的子字符串,函數已經知道它們在源代碼中的起始位置和結束位置。

在收集到最優的覆蓋范圍時,這兩種機制簡單地結合在一起:首先,我們通過遍歷整個堆來找到所有存活的函數。對于每個可見的函數,我們報告調用次數(存儲在反饋向量中,我們可以從函數中訪問)和源范圍(方便存儲在函數本身)。

請注意,由于無論是否啟用 coverage,都會維護調用計數,因此盡力服務的覆蓋不會引入任何運行時開銷。它也不使用專用的數據結構,因此既不需要顯式啟用也無需顯式禁用。

那么為什么這種模式稱為盡力服務(best-effort)呢,它的局限性是什么? 超出范圍的函數可能會被垃圾回收器釋放掉。這意味著相關的調用計數將會丟失,事實上我們完全忘記了這些函數曾經存在過。 因此“盡力服務”:即使我們盡力了,所收集的覆蓋信息也可能不完整。

精準覆蓋 (函數粒度) 

與盡力服務模式相比,精確覆蓋可確保所提供的覆蓋信息是完整的。為實現這一目標,我們會在啟用精準覆蓋后將所有反饋向量添加到V8的根參考集中,從而阻止GC對其進行回收。雖然這確保了信息無丟失,但它通過人為地保持對象存活增加內存開銷。

精準覆蓋模式還可以提供執行計數。這為精準覆蓋實施增加了另一個竅門?;叵胍幌拢看瓮ㄟ^V的解釋器調用函數時,調用計數器都會遞增,并且一旦函數訪問頻率過高,這些函數就可以升級并進行優化。 但優化的函數不再增加其調用計數器,因此必須禁用優化編譯器,以使其報告的執行次數保持準確。

精準覆蓋(塊粒度)

塊粒度覆蓋必須報告準確到獨立表達式層級的覆蓋范圍。例如,在下面的一段代碼中,塊覆蓋可以檢測到條件表達式的else分支: c從不執行,而函數粒度覆蓋只會知道函數 f(作為一個整體)被覆蓋了。

function f(a) {return a ? b : c;}f(true);

你可能從前面的部分想起我們已經在 V8 中提供了函數調用次數和源碼范圍。不幸的是,這不適合塊覆蓋的場景,我們必須實現新的機制來收集執行次數和它們相應的源碼范圍。

第一個方面是源碼范圍:假設我們擁有一個特定塊的執行計數,我們如何將它們映射到源代碼的一部分呢? 為此,我們需要在解析源文件時收集相關位置信息。在塊覆蓋之前,V8已經在某種程度上做到了這一點。一個示例是由如上所述的Function.prototype.toString而觸發的函數范圍的收集。

另一個例子是用于構造Error對象的回溯的源碼位置。但這些都不足以支持塊覆蓋; 前者僅適用于函數,而后者僅保存位置信息(例如if-else語句的if標記的位置),而不是源碼范圍。

因此,我們必須擴展解析器以收集源碼范圍。為了演示,假設我們正在使用if-else語句:

if (cond) {/* Then branch. */} else {/* Else branch. */}

當啟用塊覆蓋時,我們收集 then 和 else 分支的源碼范圍,并將它們與已解析的 IfStatement AST 節點相關聯。其他相關語言結構也是如此處理。

在解析過程中收集完源碼范圍集之后,第二個方面是在運行時跟蹤執行計數。 這是通過在生成的字節碼數組的關鍵位置插入新的專用 IncBlockCounter 字節碼來完成的。在運行時,IncBlockCounter 字節碼處理程序只是增加對應的計數器接口(可通過函數對象訪問)。

在 if-else 語句的上述示例中,這樣的字節碼將被插入在三個位置:緊接在 then 分支的主體之前,在 else 分支的主體之前,緊接在 if-else 語句之后(由于分支內可能存在非本地控制,因此需要連續的計數器)。

最后,報告塊粒度覆蓋與函數粒度報告類似。但除了調用計數(來自反饋向量)之外,我們現在還報告了感興趣的源范圍的集合以及它們的塊計數(存儲在掛起該函數的輔助數據結構中)。

如果您想了解V8中代碼覆蓋之后相關技術細節的更多信息,請參閱coverage和block coverage設計文檔。

總結

我們希望你喜歡本文中對V8原生代碼覆蓋支持的簡要介紹。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
一本一本久久a久久精品牛牛影视| 欧美性xxxxx| 2019中文字幕免费视频| 成人有码在线播放| 久久夜精品va视频免费观看| 亚洲sss综合天堂久久| 国产日韩精品在线| 欧美亚州一区二区三区| 亚洲精品动漫100p| 亚洲成人免费在线视频| 国产精品9999| 欧美与欧洲交xxxx免费观看| 日韩av片永久免费网站| 成人中文字幕在线观看| 亚洲福利影片在线| 国内成人精品视频| 日韩在线中文字幕| 亚洲第一精品久久忘忧草社区| 亚洲xxx自由成熟| 在线视频日本亚洲性| 欧美在线免费视频| 九九热这里只有在线精品视| 国产福利视频一区| 国产亚洲aⅴaaaaaa毛片| 海角国产乱辈乱精品视频| 亚洲一区二区三区乱码aⅴ| 日韩中文娱乐网| 欧美成年人视频网站欧美| 91精品国产沙发| 亚洲一区二区三区四区在线播放| 一本一本久久a久久精品牛牛影视| 国产精品三级网站| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲国产精彩中文乱码av| 福利一区视频在线观看| 国产一区二区三区在线观看视频| 国产97人人超碰caoprom| 最新国产精品亚洲| 亚洲人成在线免费观看| 国产成人精品久久二区二区| 日韩视频在线观看免费| 国产性色av一区二区| 91精品国产91久久久久久不卡| 国产精品视频一区国模私拍| 欧美一级淫片丝袜脚交| www.久久色.com| 国产精品免费在线免费| 668精品在线视频| 亚洲国产精品久久| 国产精品美女网站| 美日韩精品视频免费看| 亚洲白虎美女被爆操| 美女国内精品自产拍在线播放| 欧美日韩亚洲视频| 中文字幕视频一区二区在线有码| 久久国产天堂福利天堂| 国产在线播放不卡| 欧美在线视频免费播放| 国产精品视频免费观看www| 欧美亚洲午夜视频在线观看| 国产精品扒开腿做| 亚洲码在线观看| 神马久久久久久| 欧美精品中文字幕一区| 亚洲色图av在线| 欧美一级在线亚洲天堂| 国产香蕉97碰碰久久人人| 国产成人一区二区| 久久久久久久久久久国产| 欧美日韩精品在线观看| 日韩中文字幕亚洲| 一本大道久久加勒比香蕉| 91亚洲精品在线| 国产精品美女视频网站| 欧美电影在线观看网站| 97视频在线观看亚洲| 亚洲人在线视频| 久久精品99无色码中文字幕| 在线观看日韩欧美| 亚洲自拍偷拍第一页| 91免费精品视频| 欧美日韩激情视频| 欧美第一黄色网| 国产一区二区三区在线播放免费观看| 久久久国产精品免费| 久久久久久成人精品| 欧美国产日韩免费| 在线视频一区二区| 91系列在线播放| 成人网在线免费看| 国产91露脸中文字幕在线| 庆余年2免费日韩剧观看大牛| 欧美在线视频一区| 中文字幕亚洲一区二区三区| 日韩视频―中文字幕| 精品丝袜一区二区三区| 亚洲自拍另类欧美丝袜| 久久久午夜视频| 欧洲成人在线视频| 欧美电影免费观看网站| 中文字幕亚洲欧美一区二区三区| 欧美午夜精品伦理| 日韩精品中文字幕视频在线| 最近中文字幕mv在线一区二区三区四区| 欧美高清在线播放| 国产成人精品视| 久久久精品在线观看| 欧美激情女人20p| 欧美一级大片在线观看| 91精品久久久久久久久不口人| 91中文字幕在线| 国产美女精彩久久| 91久久嫩草影院一区二区| 日韩欧美在线网址| 大胆欧美人体视频| 国内精品一区二区三区| 日韩欧美aⅴ综合网站发布| 国产午夜精品免费一区二区三区| 92看片淫黄大片欧美看国产片| 欧美极品美女电影一区| 国产a∨精品一区二区三区不卡| 中文字幕av一区二区三区谷原希美| 国产精品久久久久久网站| 日韩中文字幕在线| 一区二区三区视频免费| 中文字幕一区二区精品| 98视频在线噜噜噜国产| 亚洲欧美精品一区| 亚洲欧美激情一区| 国产日产久久高清欧美一区| 国产精品自在线| 国产精品女主播| 亚洲免费av片| 萌白酱国产一区二区| 国产成人精品在线视频| 国产精品pans私拍| 国产成人一区二区三区电影| 欧美中文字幕在线播放| 日韩电影中文 亚洲精品乱码| 欧美性高跟鞋xxxxhd| 在线播放国产一区二区三区| 亚洲欧美国产精品久久久久久久| 最好看的2019的中文字幕视频| 日韩美女中文字幕| 成人激情视频网| 中文字幕亚洲在线| 亚洲天堂视频在线观看| 伊人伊成久久人综合网站| 狠狠躁夜夜躁人人爽天天天天97| 亚洲国产私拍精品国模在线观看| 国产一区视频在线| 国产精品久久77777| 97精品国产97久久久久久免费| 国内精品视频在线| 久久国产精品久久久| 欧美激情2020午夜免费观看| 中文字幕少妇一区二区三区| 91在线视频免费| 亚洲欧洲成视频免费观看| 亚洲第一av在线| 亚洲性线免费观看视频成熟| 国产日韩欧美成人| 国产ts一区二区| 精品视频久久久|