当前位置: 首页 > news >正文

Angular进阶之九: JS code coverage是如何运作的

  • 环境准备 需要用到的包

node 18.16.0# Javascript 代码编辑"@babel/core": "^7.24.7","@babel/preset-env": "^7.24.7","babel-loader": "^9.1.3",# 打包时使用的 module, 给代码中注入新的方法# https://v4.webpack.js.org/loaders/istanbul-instrumenter-loader/"istanbul-instrumenter-loader": "^3.0.1",# 数据收集工具"nyc": "^17.0.0",# 打包工具"webpack": "^5.92.0","webpack-cli": "^5.1.4"
  • 如何使用

1. 创建一个简单的js项目,项目结构如下
├── src
│   └── index.js 
├── .nycrc
├── .babelrc
├── package.json
├── package-lock.json
└── webpack.config.js
2. 每个文件里都有什么,怎么使用
index.js
function sum (a, b) {return a + b;
}
function reduce (a, b) {return a - b;
}// 手动调用 sum 函数来生成覆盖率
sum(1, 2);
.nycrc 配置 nyc 获取哪些文件的覆盖率 数据输出 位置
{"include": ["src"],"exclude": ["dist"],"reporter": ["html", "text"],"all": true,"report-dir": "./coverage"
}
package.json
{"build": "webpack",// 使用webpack 将index.js 打包成 dist 文件"start": "node ./dist/bundle.js",// 执行打包好的文件"coverage": "npm run build && nyc npm run start",// 使用 nyc 执行 打包好的文件并抓取数据"report:html": "nyc report --reporter=html"// 使用 nyc 生成 测试报告
}

webpack.config.js

const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {path: path.resolve(__dirname, 'dist'),filename: 'bundle.js'
},
module: {rules: [// 给 webpack 添加 istanbul-instrumenter-loader module// https://v4.webpack.js.org/loaders/istanbul-instrumenter-loader/{test: /\.js$/,exclude: /node_modules|\.test\.js$/,include: path.resolve(__dirname, 'src'),enforce: 'post',use: {loader: 'istanbul-instrumenter-loader',options: { esModules: true }}}]
},
devtool: 'inline-source-map'
};
3. 生成coverage 报告

通过上面的配置一个简单的 coverage demo 已经算是完成了
执行 npm run coverage 即可在控制台看到报告的输出
从图中可以看到 index.js 覆盖率为 66.66%

如何找到没有被覆盖的代码,可以执行 npm run report:html 生成更为详细的报告,这个命令使用 nyc report --reporter=html 读取 .nyc_output 抓取的测试输出结果 json 生成html 文件
打开 coverage 文件下的 index.html 然后点到测试的那个文件即可看到详细的代码覆盖文件

  • 如何实现

https://v4.webpack.js.org/loaders/istanbul-instrumenter-loader/
code coverage 主要通过 webpack loaders istanbul-instrumenter-loader 来实现的
通过观察不使用和使用这个 loaders 的打包文件可以发现,使用 istanbul-instrumenter-loader 打包后的文件,会被注入一个非常大的 function 将当前文件里所有的function 判断 变量都做上了编号

{"path": "/Users/********/Desktop/coverage1/src/index.js","statementMap": {"0": { start: { line: 2, column: 4 }, end: { line: 2, column: 17 } },},"fnMap": {"0": { name: "sum", decl: { start: { line: 1, column: 9 }, end: { line: 1, column: 12 } }, loc: { start: { line: 1, column: 20 }, end: { line: 3, column: 1 } }, line: 1 }},"branchMap": { '0': { loc: { start: { line: 8, column: 0 }, end: { line: 10, column: 1 } }, type: 'if', locations: [{ start: { line: 8, column: 0 }, end: { line: 10, column: 1 } }, { start: { line: 8, column: 0 }, end: { line: 10, column: 1 } }], line: 8 }},"s": { '0': 0, '1': 0, '2': 0, '3': 0, '4': 0 }, "f": { '0': 0, '1': 0 }, "b": { '0': [0, 0] }
}function sum (a, b) { cov_29gy9r9jfk.f[0]++; cov_29gy9r9jfk.s[0]++; return a + b; 
} 
// statementMap: 记录定义变量的开始结束位置
// fnMap: 记录 Function 的 开始结束为止, function name
// branchMap: 记录判断的 开始结束为止
// s,f,b: 调用方法的时候调用封装的大方法然后给对应的变量 ++ 记录,调用次数
  • 编译过后的代码如何映射在原始文件中

source-map 中都有什么

{"version": 3,// 当前使用 source-map 的版本"file": "bundle.js",// 编译后的文件名"mappings": ";;;;;AAAA;AACA;AACA;AACA;AACA;AACA",// 这是最重要的内容,表示了源代码及编译后代码的关系"sources": [// 源文件名"webpack://manual/./src/index.js"],"sourcesContent": [// 转换前的的代码"function sum (a, b) {\r\n    return a + b;\r\n}\r\nsum(1, 2);\r\n\r\n\r\n"],"names": [],// 转换前的变量和属性名称"sourceRoot": ""// 所有的sources相对的根目录
}

source-map 如何对应到 源文件中的位置
这里需要用到上面的 mappings
首先 mappings 的内容其实是 Base64 VLQ 的编码表示。
内容由三部分组成,分别为:

  1. 英文,表示源码及压缩代码的位置关联
  2. 逗号,分隔一行代码中的内容。比如说 console.log(a) 就由 console log a 三部分组成,所以存在两个逗号。
  3. 分号,代表换行

所以 mappings 中的每一个字母都代表每个代码对应的位置,下面是当前 mappings 的解析结果

https://www.murzwin.com/base64vlq.html

相关文章:

Angular进阶之九: JS code coverage是如何运作的

环境准备 需要用到的包 node 18.16.0# Javascript 代码编辑"babel/core": "^7.24.7","babel/preset-env": "^7.24.7","babel-loader": "^9.1.3",# 打包时使用的 module, 给代码中注入新的方法# http…...

el-table 鼠标移入更改悬停背景颜色

鼠标悬停时需要更改当前行背景颜色,一开始写的颜色会改变,但是一闪而过就没了 这是因为移入移出的动画效果导致的 .el-table__body {.el-table__row:hover {background-color: pink !important;}} 更改为后面的代码,就可以了 .el-table__…...

【《无主之地3》风格角色渲染在Unity URP下的实现_角色渲染(第四篇) 】

文章目录 概要描边问题外秒变分叉解决办法1:测试效果如下:外秒变分叉解决办法2:URP管线下PBR渲染源码关键词解释:完整shader代码如下:URP管线下二次元皮肤渲染源码URP管线下二次元头发渲染源码简要介绍文章的目的、主要内容和读者将获得的知识。 概要 提示:《无主之地3》…...

【linux服务器篇】-Redis-RDM远程连接redis

redis desktop manager 使用远程连接工具RDM连接redis 市面上比较常见的其中一款工具redis desktop manager 简单的说: Redis Desktop Manager 简单的来讲就是Redis可视化工具,可以让我们看到Redis中存储的内容。 redis desktop manager是一款功能强…...

【pytorch15】链式法则

x到u再到y,可以理解为x是输入,中间层hidden layer 是u,最后y是pred 对于一个简单的线性层可以展开得到y的表达式,但是对于实际的神经网络还要加上激活函数,此时展开就非常的复杂,不能够一次到位&#xff0c…...

C#用链表和数组分别实现堆栈

1.链表 实现栈的四个基本功能 入栈 出栈 长度 栈顶值 public class 基础 : MonoBehaviour {public class MyStack{//定义每一个元素的数据结构 //下一个元素 和 该元素的值public class StackData{public StackData next;public object data;public StackData(StackData next,…...

【AI原理解析】—强化学习(RL)原理

目录 一、基本原理 二、基本框架与要素 三、学习过程 四、关键概念 五、算法实现 六、应用领域 七、总结 强化学习(Reinforcement Learning, RL) 一、基本原理 强化学习的基本原理是基于“试错学习”(trial-and-error learning&…...

java解析请求的字符串参数Content-Disposition: form-data;和拼接的键值对

项目场景: 获取到http请求的参数,已经被字符串接收了,需求是需要从字符串中解析出来。 一种情况是:Content-Disposition: form-data; name"userCode" 另一种是:key1value1&key2value2&key3value3…...

活动回顾|2024 MongoDB Developer Day圆满收官!

上周六,MongoDB专家与团队在深圳 与90位开发者度过了充实一日 至此,2024 MongoDB Developer Day 北上深三站之行全部圆满结束! 一文回顾本次活动全程与精彩影像! MongoDB Developer Day 专为开发者定制的技术盛宴 全天沉浸动手实…...

MySQL资源组的使用方法

MySQL支持创建和管理资源组,并允许将服务器内运行的线程分配给特定的组,以便线程根据组可用的资源执行。组属性允许控制其资源,以启用或限制组中线程的资源消耗。DBA可以针对不同的工作负载适当地修改这些属性。 目前,CPU时间是一…...

python--实验7 函数(1)

知识点 函数的定义与调用 函数分类:内置函数和自定义函数。函数定义:使用def关键字定义函数,包括函数名、参数列表和函数体。注意: (1)即使该函数不需要接收任何参数,也必须保留一对空的圆括号…...

【力扣】数组中的第K个最大元素

一、题目描述 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入: [3,2,1,5,…...

WTM的项目中EFCore如何适配人大金仓数据库

一、WTM是什么 WalkingTec.Mvvm框架(简称WTM)最早开发与2013年,基于Asp.net MVC3 和 最早的Entity Framework, 当初主要是为了解决公司内部开发效率低,代码风格不统一的问题。2017年9月,将代码移植到了.Net Core上&…...

互联网3.0时代的变革者:华贝甄选大模型创新之道

在当今竞争激烈的商业世界中,华贝甄选犹如一颗璀璨的明星,闪耀着独特的光芒。 华贝甄选始终将技术创新与研发视为发展的核心驱动力。拥有先进的研发团队和一流设施,积极探索人工智能、大数据、区块链等前沿技术,为用户提供高性能…...

Tomcat的安全配置

1、生产环境优化 2、部分漏洞修复 转载自风险评估:Tomcat的安全配置,Tomcat安全基线检查加固-CSDN博客...

[笔记] 卷积 - 01 变速箱需要放置多少个加速度传感器?

1.讨论范围 本帖主要对卷积运算的过程和物理意义进行基本的展开,不涉及具体的验算过程。 最终所要达成的目标是,能够自然地判断某种物理现象或者某个测量目标是否与卷积运算有关,以及如何进行测量,搜集数据,调用三方…...

Maya崩溃闪退常见原因及解决方案

Autodesk Maya 是一款功能强大的 3D 计算机图形程序,被电影、游戏和建筑等各个领域的设计师广泛使用。然而,Maya 就像任何其他软件一样可能会发生崩溃问题。在前文中,小编给大家介绍了3ds Max使用V-Ray渲染时的崩溃闪退解决方案: …...

编码与梦想:我的CSDN创作5周年

五年前的今天,我带着对技术的热爱和对知识的渴望,踏上了CSDN的创作之旅。这个平台对于我来说,不仅仅是一个分享和学习的场所,更是我成长和自我实现的见证。 机缘 记得那时,我正为了一个编程难题而苦恼,偶…...

Vue2 基础十Vuex

代码下载 Vuex 概述 组件之间共享数据的方式: 父组件向子组件传值,是以属性的形式绑定值到子组件(v-bind),然后子组件用属性props接收。子组件向父组件传值,子组件用 $emit() 自定义事件,父组…...

【大模型】驾驭未知领域:LLM如何处理域外或无意义的提示

驾驭未知领域:LLM如何处理域外或无意义的提示 引言一、概念解析1.1 域外提示1.2 无意义提示二、LLM处理策略2.1 上下文推断2.2 缺省回答2.3 模糊处理2.4 求助于常识三、实例对比3.1 域外提示实例3.2 无意义提示实例四、挑战与局限五、未来展望六、结语附录:术语解释与参考资料…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

基于Springboot+Vue的办公管理系统

角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下&#xf…...

相关类相关的可视化图像总结

目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...

GeoServer发布PostgreSQL图层后WFS查询无主键字段

在使用 GeoServer(版本 2.22.2) 发布 PostgreSQL(PostGIS)中的表为地图服务时,常常会遇到一个小问题: WFS 查询中,主键字段(如 id)莫名其妙地消失了! 即使你在…...

RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上

一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema,不需要复杂的查询,只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 :在几秒钟…...

宠物车载安全座椅市场报告:解读行业趋势与投资前景

一、什么是宠物车载安全座椅? 宠物车载安全座椅是一种专为宠物设计的车内固定装置,旨在保障宠物在乘车过程中的安全性与舒适性。它通常由高强度材料制成,具备良好的缓冲性能,并可通过安全带或ISOFIX接口固定于车内。 近年来&…...

循环语句之while

While语句包括一个循环条件和一段代码块&#xff0c;只要条件为真&#xff0c;就不断 循环执行代码块。 1 2 3 while (条件) { 语句 ; } var i 0; while (i < 100) {console.log(i 当前为&#xff1a; i); i i 1; } 下面的例子是一个无限循环&#xff0c;因…...

【R语言编程——数据调用】

这里写自定义目录标题 可用库及数据集外部数据导入方法查看数据集信息 在R语言中&#xff0c;有多个库支持调用内置数据集或外部数据&#xff0c;包括studentdata等教学或示例数据集。以下是常见的库和方法&#xff1a; 可用库及数据集 openintro库 该库包含多个教学数据集&a…...

无头浏览器技术:Python爬虫如何精准模拟搜索点击

1. 无头浏览器技术概述 1.1 什么是无头浏览器&#xff1f; 无头浏览器是一种没有图形用户界面&#xff08;GUI&#xff09;的浏览器&#xff0c;它通过程序控制浏览器内核&#xff08;如Chromium、Firefox&#xff09;执行页面加载、JavaScript渲染、表单提交等操作。由于不渲…...