关于后台的代码增量的逻辑已经有比较成熟的方案了。 根据javaparser解析前后的文件的方法列表,判断是否有新增或者修改的方法。

前端代码覆盖率增量覆盖的困难

针对前端代码覆盖率并不能像java那块那么简单,有专门的javascript的解析器,能够获取到这个js文件中所有的方法。所以套用原有的java那套逻辑基本是不太可行的。所以我们需要另辟蹊径来解决这个问题。

java的增量代码diff 我们是从解析源码的文件入手的,那针对js既然这套不行,有没有方式能够从覆盖率结果数据入手,去解决这个事情呢?
如果了解前端代码覆盖率的同学可能都清楚,前端的覆盖率收集是根据浏览器提交的coverage数据来的。而coverage的数据其实是大有来头的。

我们看一个数据


/**** * `path` - the file path for which coverage is being tracked* * `statementMap` - map of statement locations keyed by statement index* * `fnMap` - map of function metadata keyed by function index* * `branchMap` - map of branch metadata keyed by branch index* * `s` - hit counts for statements* * `f` - hit count for functions* * `b` - hit count for branches*/
{path: filePath,statementMap: {"5": {"end": {"line": 10,"column": 30},"start": {"line": 10,"column": 26}},},fnMap: {},branchMap: {},s: {"5": 10290,},f: {},b: {}
}

以上的内容中statementMap 中的5代表标记的对应的代码块为第10行,列则是从26到30, 同时映射到s中 这个代码块被执行了10290次。
这块的数据其实也完整的说明了对应的文件中,代码/分支/方法是否覆盖的情况。

思路

那么是不是可以这么去考虑呢?从git diff中对比得到对应文件的改动行数,然后再对应到这块的数据上,如果修改的代码行 是在statemanMap/ fnMap/ branchMap 的覆盖范围的话就保留这块的数据,如果说改动行中,不存在有这块的内容则从对象中将这块的内容剔除掉。这样子就可以得到增量的数据了。

但是我们是不是直接针对用户提交的coverage数据做处理呢?

答案是不行的。 我们需要了解一个问题,之前我们在 聊聊前端代码覆盖率 (长文慎入) 中提到过用户提交的coverage数据并不是完整的反应到原本的代码行上,主要是针对typescript这块,因为如果你的编译是经过ts-loader -> babel-loader 处理的话。得到的coverage中的数据中的line的值,其实跟源码中的line会出现不一致的情况。而istanbul这块是会根据sourceMap 重新映射回去的。

那哪里的数据才是正在正确的呢? 答案其实在通过nyc api生成的报告目录下, 当你的api指定了reporter包含有 json的情况下,就会在覆盖率报告的目录下生成有 coverage-final.json。 这里的数据其实跟coverage数据基本是一致的,并且这里的数据已经经过istanbul校正过。所以我们可以信任这块的数据。

解决

从git api中获取到改动行,判断statemanMap/ fnMap/ branchMap 的开始行及结束行的范围是否包含了改动行。如果在对应的范围那么则保留对象数据,如果不在,则移除掉对应的对象。如此剩下的就是改动范围的覆盖情况

所以我们可以这么处理

/*** 根据代码codeDiff,过滤掉未改动的语句* @param fileFinal 对应文件的覆盖率数据情况,格式就是我们上述提到的数据* @param statements * @return*/
private void handleStatements(List<Integer> codeDiff, Coverage fileFinal, CoverageSummary statements, CoverageSummary lines) {List<String> keys = new ArrayList<>();Map<Integer, Integer> line = new HashMap<>();// 这里的key 是0, 1, 2, 3  "statementMap":{"0":{"start":{"line":9,"column":22},"end":{"line":39,"column":1}} ;; "s":{"0":10150,"1":10150,"2":0,"3":0},for (String key : fileFinal.getStatementMap().keySet()) {if (!isDiff(codeDiff, fileFinal.getStatementMap().get(key).getStart().getLine(), fileFinal.getStatementMap().get(key).getEnd().getLine())) {keys.add(key);}}// 将不包含改动行的桩删除for (String key : keys) {fileFinal.getStatementMap().remove(key);fileFinal.getS().remove(key);}computeCoverageSummary(getLineCoverage(fileFinal), lines);computeCoverageSummary(fileFinal.getS(), statements);
}

这里关于statement/line/fun的统计计算这里就不详细描述了,主要可以参考 file-coverage 中的各个值的计算逻辑。

所以我们举一个简单的例子来说明下:假设 client/src/utils/location.js 的coverage数据如下:

{"/app/thirdCode/c94933a0-7250-11eb-8c93-c9620716ef34_1/xxx/client/src/utils/location.js": {"path": "/app/thirdCode/c94933a0-7250-11eb-8c93-c9620716ef34_1/xxx/client/src/utils/location.js","statementMap": {"0": {"start": {"line": 9,"column": 39},"end": {"line": 9,"column": 54}},"1": {"start": {"line": 10,"column": 25},"end": {"line": 10,"column": 52}},"2": {"start": {"line": 11,"column": 26},"end": {"line": 11,"column": 48}},"3": {"start": {"line": 13,"column": 4},"end": {"line": 19,"column": 5}},"4": {"start": {"line": 14,"column": 8},"end": {"line": 17,"column": 9}},"5": {"start": {"line": 15,"column": 12},"end": {"line": 15,"column": 37}},"6": {"start": {"line": 16,"column": 12},"end": {"line": 16,"column": 21}},"7": {"start": {"line": 18,"column": 8},"end": {"line": 18,"column": 37}},"8": {"start": {"line": 20,"column": 22},"end": {"line": 20,"column": 45}},"9": {"start": {"line": 21,"column": 20},"end": {"line": 21,"column": 72}},"10": {"start": {"line": 23,"column": 4},"end": {"line": 25,"column": 5}},"11": {"start": {"line": 24,"column": 8},"end": {"line": 24,"column": 50}},"12": {"start": {"line": 27,"column": 4},"end": {"line": 27,"column": 19}},"13": {"start": {"line": 36,"column": 25},"end": {"line": 36,"column": 78}},"14": {"start": {"line": 37,"column": 19},"end": {"line": 40,"column": 10}},"15": {"start": {"line": 38,"column": 8},"end": {"line": 38,"column": 31}},"16": {"start": {"line": 39,"column": 8},"end": {"line": 39,"column": 19}},"17": {"start": {"line": 42,"column": 4},"end": {"line": 44,"column": 5}},"18": {"start": {"line": 43,"column": 8},"end": {"line": 43,"column": 29}},"19": {"start": {"line": 46,"column": 4},"end": {"line": 48,"column": 5}},"20": {"start": {"line": 47,"column": 8},"end": {"line": 47,"column": 35}},"21": {"start": {"line": 50,"column": 4},"end": {"line": 50,"column": 18}}},"s": {"0": 43,"1": 43,"2": 43,"3": 43,"4": 43,"5": 0,"6": 0,"7": 43,"8": 43,"9": 43,"10": 43,"11": 43,"12": 43,"13": 2184,"14": 2184,"15": 6552,"16": 6552,"17": 2184,"18": 2184,"19": 0,"20": 0,"21": 0},"_coverageSchema": "1a1c01bbd47fc00a2c39e90264f33305004495a9","hash": "26596d813cde8cfd5d6449001d4e49f4283c164a"}
}

以上的数据我们省掉了 fnMap以及branchMap的数据。

而我们的的codeDiff的数据:

说明改动的行数只是49-50行

所以处理过的coverage的结果数据为

{"s": {"21": 0},"hash": "26596d813cde8cfd5d6449001d4e49f4283c164a","path": "/app/thirdCode/c94933a0-7250-11eb-8c93-c9620716ef34_1/xxx/client/src/utils/location.js","statementMap": {"21": {"end": {"line": 50,"column": 18},"start": {"line": 50,"column": 4}}},"_coverageSchema": "1a1c01bbd47fc00a2c39e90264f33305004495a9"
}

相应的fn, branch也是相应的处理。

不足:

上述的方式其实存在一个问题,前端的增量覆盖计算的逻辑并不是跟java的增量的逻辑一致的,java的最小增量的计算单位是方法,而前端的最小增量单位是语句。所以并不能很好的得到结果是前端某个代码改动后,需要覆盖这个代码所在的方法的内容,而只是需要覆盖到改动的语句就可以了。

前端代码覆盖率增量计算相关推荐

  1. 前端代码覆盖率遇到问题及总结(一)

    在讲之前得说下 前端覆盖率的水真的是很深的,其实到目前为止还有很多未解之谜,由于对babel的编译以及ast了解的不是很多.所以确实分析问题起来很困难. 前端代码覆盖率方案 关于前端代码覆盖率还不了解 ...

  2. 非常复杂,上双11数据大屏背后的秘密:大规模流式增量计算及应用

    回顾大数据技术领域大事件,最早可追溯到06年Hadoop的正式启动,而环顾四下,围绕着数据库及数据处理引擎,业内充斥着各种各样的大数据技术.这是个技术人的好时代,仅数据库领域热门DB就有300+,围绕 ...

  3. 一个前端js分页计算

    <div id=rrapp><table id="rightHolder" class="layui-table" lay-skin=&quo ...

  4. 音视频中时间戳增量计算

    https://blog.csdn.net/u012635648/article/details/78695619 https://blog.csdn.net/peckjerry/article/de ...

  5. 2021前端面试经典计算题总结。

    1. 给出一个string, 倒序输出该句子,其中的每个单词本身并不会翻转, 比如 "I love China" ->"China love I" var ...

  6. 前端遇上Go: 静态资源增量更新的新实践

    为什么要做增量更新 美团金融的业务在过去的一段时间里发展非常快速.在业务增长的同时,我们也注意到,很多用户的支付环境,其实是在弱网环境中的. 大家知道,前端能够服务用户的前提是 JavaScript ...

  7. iOS代码覆盖率(二)-增量覆盖率自动化实践

    全量代码覆盖率可以直观的看到整个App的代码的覆盖率情况,但是往往有用的或者被关注的是增量代码覆盖率数据.经过不断的学习和探索,发现在基于git diff能力,通过一系列的处理获取我们想要的增量的信息 ...

  8. 头条项目推荐的相关技术(四):离线文章画像的增量更新及离线文章相似度计算

    1. 写在前面 这里是有关于一个头条推荐项目的学习笔记,主要是整理工业上的推荐系统用到的一些常用技术, 这是第四篇, 上一篇文章整理了离线文章画像的计算过程,主要包括TFIDF和TextRank两种技 ...

  9. 大数据计算框架与平台--深入浅出分析

    http://mp.weixin.qq.com/s/s2DnbgieeQockaLKdZDCzA?utm_source=tuicool&utm_medium=referral 1. 前言 计算 ...

最新文章

  1. 用AI还原李焕英老照片动态影像
  2. gitk、Git GUI 图形化工具中文显示乱码的解决方案
  3. 正则表达式懒惰贪婪和replace函数
  4. PostgreSQL 电商业务(任意维度商品圈选应用) - json包range数组的命中优化 - 展开+索引优化...
  5. Mac OS X 在Finder新建文本文件
  6. ubuntu使用KVM创建虚拟机
  7. H5页面在iOS网页数字颜色自动被改变成蓝色
  8. 桌面虚拟化之用户行为审计
  9. VMware vCenter Server6.5升级至6.7
  10. Deepin Linux已经做得相当不错了
  11. delphi xe3 oracle,delphixe3
  12. 卸载office 2003出现pro11.msi
  13. 目标检测算法综述(近20年)
  14. imx6ull-qemu 裸机教程1:GPIO,IOMUX,I2C
  15. 大数据毕设 - 网络游戏数据分析与可视化(python 大数据)
  16. STC12驱动PCF8575
  17. UG NX 12 矢量构造器
  18. XCode下Object C和C++混合编译
  19. 从DPU看未来网络架构的演进趋势
  20. 【AI】《ResNet》论文解读、代码实现与调试找错

热门文章

  1. oracle impdp参数,expdp/impdp参数解释
  2. impdp 并行_Oracle expdp/impdp常用性能优化方法
  3. 上海工作2年以上工资是几k
  4. 使用tls生成腾讯云的密钥
  5. picrust2功能预测-从qiime2安装到数据分析
  6. 陕西师范大学计算机类专业咋样,陕西师范大学计算机科学学院
  7. 《数据之巅》读书笔记
  8. go语言defer使用
  9. 证明多元函数可导,但不连续_20160519
  10. ROS学习|Behavoir Tree(BT树)--c++实现第二节