iis服务器助手广告
返回顶部
首页 > 资讯 > 前端开发 > html >JavaScript代码覆盖的示例分析
  • 942
分享到

JavaScript代码覆盖的示例分析

2024-04-02 19:04:59 942人浏览 薄情痞子
摘要

这篇文章给大家分享的是有关javascript代码覆盖的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。它为什么是有用的? 作为一名JavaScript开发者,你可能经常发

这篇文章给大家分享的是有关javascript代码覆盖的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

它为什么是有用的?

作为一名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) {

} else {

}

当启用块覆盖时,我们收集 then 和 else 分支的源码范围,并将它们与已解析的 IfStatement AST 节点相关联。其他相关语言结构也是如此处理。

在解析过程中收集完源码范围集之后,第二个方面是在运行时跟踪执行计数。 这是通过在生成的字节码数组的关键位置插入新的专用 IncBlockCounter 字节码来完成的。在运行时,IncBlockCounter 字节码处理程序只是增加对应的计数器接口(可通过函数对象访问)。

在 if-else 语句的上述示例中,这样的字节码将被插入在三个位置:紧接在 then 分支的主体之前,在 else 分支的主体之前,紧接在 if-else 语句之后(由于分支内可能存在非本地控制,因此需要连续的计数器)。

最后,报告块粒度覆盖与函数粒度报告类似。但除了调用计数(来自反馈向量)之外,我们现在还报告了感兴趣的源范围的集合以及它们的块计数(存储在挂起该函数的辅助数据结构中)。

如果您想了解V8中代码覆盖之后相关技术细节的更多信息,请参阅coverage和block coverage设计文档。

感谢各位的阅读!关于“JavaScript代码覆盖的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: JavaScript代码覆盖的示例分析

本文链接: http://www.lsjlt.com/news/75268.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript代码覆盖的示例分析
    这篇文章给大家分享的是有关JavaScript代码覆盖的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。它为什么是有用的 作为一名JavaScript开发者,你可能经常发现...
    99+
    2024-04-02
  • Mysql覆盖索引的示例分析
    小编给大家分享一下Mysql覆盖索引的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!概念如果索引包含所有满足查询需要的数...
    99+
    2024-04-02
  • CSS样式覆盖规则的示例分析
    这篇文章给大家分享的是有关CSS样式覆盖规则的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。首先需要明确的是,很多情况都会导致一个元素被运用上多种样式,样式覆盖的规则也需...
    99+
    2024-04-02
  • mysql覆盖索引高性能的示例分析
    这篇文章主要介绍mysql覆盖索引高性能的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、高性能的原因索引通常比记录要小,覆盖索引查询只需要读索引,而不需要读记录。索引都按照值的大小进行顺序存储,相比与随机...
    99+
    2023-06-15
  • mysql索引覆盖实例分析
    本文实例讲述了mysql索引覆盖。分享给大家供大家参考,具体如下: 索引覆盖 如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行,不需要回行到磁盘再找数据。这种查询速度非常快,称为“索引覆盖”。...
    99+
    2024-04-02
  • echarts鼠标覆盖高亮显示节点的示例分析
    这篇文章主要为大家展示了“echarts鼠标覆盖高亮显示节点的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“echarts鼠标覆盖高亮显示节点的示例分析...
    99+
    2024-04-02
  • JavaScript手写代码的示例分析
    小编给大家分享一下JavaScript手写代码的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1. 实现一个new操作符...
    99+
    2024-04-02
  • JavaScript代码简化的示例分析
    这篇文章主要为大家展示了“JavaScript代码简化的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JavaScript代码简化的示例分析”这篇文章吧...
    99+
    2024-04-02
  • JavaScript单行代码示例分析
    这篇文章主要介绍JavaScript单行代码示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!什么是单行代码?单行代码是一种代码实践,其中我们仅用一行代码执行某些功能。01-随机获取布尔值此函数将使用Math.r...
    99+
    2023-06-15
  • 基于input框覆盖掉数字英文的示例分析
    小编给大家分享一下基于input框覆盖掉数字英文的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!例子1:<inpu...
    99+
    2024-04-02
  • HTML覆盖样式顺序实例分析
    这篇文章主要讲解了“HTML覆盖样式顺序实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“HTML覆盖样式顺序实例分析”吧! 正常情况下,选最后一个,...
    99+
    2024-04-02
  • thinkphp5.0.X全版本变量覆盖导致RCE的示例分析
    小编给大家分享一下thinkphp5.0.X全版本变量覆盖导致RCE的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!简介总是碰到一些thinkphp5.0.X的站点,网上搜索漏洞利用payload会有好几种,变量覆...
    99+
    2023-06-14
  • PHP中变量覆盖漏洞的案例分析
    这篇文章主要介绍了PHP中变量覆盖漏洞的案例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.extract()变量覆盖1.extract()extract() 函数从数...
    99+
    2023-06-14
  • python自动统计zabbix系统监控覆盖率的示例代码
    脚本主要功能: 1)通过zabbix api接口采集所有监控主机ip地址; 2)通过cmdb系统(蓝鲸)接口采集所有生产主机IP地址、主机名、操作系统、电源状态; 3)以上2步返回数...
    99+
    2024-04-02
  • Javascript中添加事件到脚本被覆盖的示例
    这篇文章主要介绍了Javascript中添加事件到脚本被覆盖的示例,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。问题:添加到脚本中被覆盖<!DOCTYPE h...
    99+
    2023-06-14
  • Go实现替换(覆盖)文件某一行内容的示例代码
    目录1、前言2、实现覆盖某一行文件内容的思路3、实现覆盖某一行内容的代码示例4、扩展1、前言 有这样一个需求,我们查找到文件中带有某个关键词的一行内容后,对该行内容进行替换,替换成我...
    99+
    2024-04-02
  • 如何在GitLab中进行持续集成的代码覆盖率分析
    标题:GitLab持续集成中的代码覆盖率分析及实例引言:随着软件开发变得越来越复杂,代码覆盖率分析成为了评估软件测试质量的重要指标之一。而采用持续集成来进行代码覆盖率分析可以帮助开发团队实时监控自己的代码质量,提高软件开发效率。本文将介绍如...
    99+
    2023-10-22
    gitlab 持续集成 代码覆盖率
  • idea自带Jacoco/idea自动测试语句覆盖率的示例分析
    这篇文章主要介绍了idea自带Jacoco/idea自动测试语句覆盖率的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、准备工作首先你肯定必须要有测试的项目,这个是...
    99+
    2023-06-14
  • Python代码示例分析
    这篇文章主要介绍了Python代码示例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python代码示例分析文章都会有所收获,下面我们一起来看看吧。题目加粗,注意事项红色(...
    99+
    2024-04-02
  • 如何使用开源JavaScript代码覆盖率工具ScriptCover
    如何使用开源JavaScript代码覆盖率工具ScriptCover,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Google已经宣布Scri...
    99+
    2024-04-02
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作