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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/43668.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

群晖NAS配置WebDav服务结合内网穿透实现跨平台云同步思源笔记

文章目录 前言1. 开启群晖WebDav 服务2. 本地局域网IP同步测试3. 群晖安装Cpolar4. 配置远程同步地址5. 笔记远程同步测试6. 固定公网地址7. 配置固定远程同步地址 前言 本教程主要分享如何将思源笔记、cpolar内网穿透和群晖WebDav三者相结合,实现思源笔记的云同步…

打开excel时弹出stdole32.tlb

问题描述 打开excel时弹出stdole32.tlb 如下图: 解决方法 打开 Microsoft Excel 并收到关于 stdole32.tlb 的错误提示时,通常意味着与 Excel 相关的某个组件或类型库可能已损坏或不兼容。 stdole32.tlb 是一个用于存储自动化对象定义的类型库&#x…

vue 切换主题色切换主题色切换主题色切换主题色切换主题色

第一种&#xff1a;使用CSS变量 CSS变量&#xff08;Custom Properties&#xff09;是CSS的一种新特性 1.实现需求&#xff1a;自定义颜色 定义变量 全局的theme.css :root {--primary-color:red; }在组件中使用这些变量 demo.vue <template><div class"main…

海外多语言盲盒APP系统开发

随着盲盒的全球化发展&#xff0c;盲盒已经成为了一个热门行业&#xff0c;不仅深受我国消费者的青睐&#xff0c;更是深受海外消费者的喜爱。目前&#xff0c;盲盒出海已经成为了企业拓展市场的新机会。 在数字化时代&#xff0c;海外盲盒APP为企业提供了一个快速打开海外盲盒…

应急响应——勒索病毒

先上搜索引擎上搜 也可以用360来杀 但是都无法解密 可以解密的&#xff1a; linux

【嵌入式DIY实例-ESP8266篇】-LCD ST7735显示BME280传感器数据

LCD ST7735显示BME280传感器数据 文章目录 LCD ST7735显示BME280传感器数据1、硬件准备与接线2、代码实现本文中将介绍如何使用 ESP8266 NodeMCU 板(ESP12-E 模块)和 BME280 气压、温度和湿度传感器构建气象站。 NodeMCU 微控制器 (ESP8266EX) 从 BME280 传感器读取温度、湿度…

优秀策划人必逛的地方,你不会还不知道吧?

道叔今天依然记得当初刚入行的时候&#xff0c;每天为完成策划任务&#xff0c;焦虑的整晚睡不着觉的痛苦。 但其实……很多时候&#xff0c;选择比努力更重要 优秀的策划和文案&#xff0c;也从来不是天生&#xff0c;你要走的路&#xff0c;前人都已经走过,你要做的仅仅是整…

python破解密码·筛查和选择

破解密码时可能遇到的几种情况 ① 已知密码字符&#xff0c;破排序 ② 已知密码位数&#xff0c;破字符 ③ 已知密码类型&#xff0c;破字位 ④ 已知部分密码&#xff0c;破未知 ⑤ 啥都不知道&#xff0c;盲破&#xff0c;玩完 ⑥ 已知位数、字符、类型、部分密码中的几个&am…

技术速递|VS Code Java 6月更新 - 项目设置功能增强!大量 Spring 新特性

作者&#xff1a;Nick Zhu 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎阅读 Visual Studio Code for Java 的六月更新&#xff01;在这篇博客中&#xff0c;我们将分享项目设置项目的重要更新以及一系列 Spring 的功能改进&#xff0c;让我们开始吧&#xff01; 项目设…

如何魔改vnstat-docker项目使其支持每1分钟采样?

文章目录 一、概述二、官网参考1. 官网地址2. 查看打包过程3.打包命令 三、修改过的文件四、部署运行1. 编排文件2. 运行效果 一、概述 接前文 网络流量监控神器vnStat初探 我们已经了解了vnStat的作用、使用和docker部署。 同时也了解到官方版本支持的采样统计间隔最小为5分…

使用tkinter拖入excel文件并显示

使用tkinter拖入excel文件并显示 效果代码 效果 代码 import tkinter as tk from tkinter import ttk from tkinterdnd2 import TkinterDnD, DND_FILES import pandas as pdclass ExcelViewerApp(TkinterDnD.Tk):def __init__(self):super().__init__()self.title("Excel…

C# Bitmap类型与Byte[]类型相互转化详解与示例

文章目录 一、Bitmap类型转Byte[]类型使用Bitmap类的Save方法使用Bitmap类的GetBytes方法 二、Byte[]类型转Bitmap类型使用MemoryStream将Byte[]数组转换为Bitmap对象使用System.Drawing.Imaging.BitmapImage类 总结 在C#编程中&#xff0c;Bitmap类型和Byte[]类型之间的相互转…

Linux:进程间通信(二.共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)

Linux&#xff1a;进程间通信&#xff08;二.共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量&#xff09; 上次结束了进程间通信一&#xff1a;Linux&#xff1a;进程间通信&#xff08;一.初识进程间通信、匿名管道与命名管道、共享内存&#xff09; 文章目录 …

C++进阶:继承和多态

文章目录 ❤️继承&#x1fa77;继承与友元&#x1f9e1;继承和静态成员&#x1f49b;菱形继承及菱形虚拟继承&#x1f49a;继承和组合 ❤️多态&#x1fa77;什么是多态&#xff1f;&#x1f9e1;多态的定义以及实现&#x1f49b;虚函数&#x1f49a;虚函数的重写&#x1f499…

吴恩达机器学习作业ex8:K 异常检测和推荐系统(Python实现)详细注释

文章目录 1 异常检测1.1 高斯分布1.2 估计高斯参数1.3 选择阈值 ε1.4 高维数据集 2 推荐系统2.1 电影评分数据集2.2 协作过滤学习算法2.2.1 协同过滤成本函数2.2.2 梯度协同过滤2.2.3 Regularized cost function2.2.4 正则梯度 2.3 学习电影推荐2.3.1 推荐 后记 1 异常检测 在…

c++入门基础篇(上)

前言&#xff1a; 我们在之前学完了c语言的大部分语法知识&#xff0c;是不是意味着我们可以马上从事开发呢&#xff1f;其实行业中的绝大部分岗位都用不到c语言&#xff0c;那我们为什么要学c语言呢。c语言虽然和我们日常开发没有很大的关系&#xff0c;但是学习c语言可以为我…

14.x86游戏实战-汇编指令cmp test

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

LLm与微调

推荐尝试的微调模型 internlm2-20b-chat&#xff0c;internlm2-7b-chat&#xff0c; Qwen2-7B-Instruct, Qwen2-1.5B-Instruct, Qwen1.5-32B-Chat (Qwen2-0.5B、Qwen2-1.5B, qwen1.5的4B&#xff0c;7B&#xff0c;14B&#xff0c;32B) glm-4-9b-chat, glm-4-9b-chat-1m, gl…

SLAM相关知识

目前在SLAM上的传感器主要分为两大类&#xff1a;激光雷达和摄像头 激光雷达&#xff1a;单线、多线 摄像头&#xff1a;单目相机&#xff08;普通USB相机&#xff09;、双目相机&#xff08;2个普通的USB相机&#xff09;、单目结构光&#xff08;深度相机&#xff09;、双目…

【二】Ubuntu24虚拟机在Mac OS的VMware Fusion下无法联网问题

文章目录 1.环境背景2. 需求背景3. 解决方法3.1 在mac的终端查看虚拟机NAT网络3.2 查看unbuntu节点2的网络配置3.3 问题定位与解决3.3.1 检查是否有冲突3.3.2 冲突解决方法 4. 总结4.1 NAT 网关的原理4.2 VMware Fusion 的 NAT 模式4.3 为什么网关冲突会引起问题4.4 理解配置冲…