2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

前端精准测试探索:覆盖率实时统计工具

  • 2019-10-13
  • 本文字数:2788 字

    阅读完需:约 9 分钟

前端精准测试探索:覆盖率实时统计工具

背景

随着业务增长,随之而来的前端需求激增,如何在有限的时间内保证前端代码的质量。通过测试同学单方面的保障,还是免不了前端线上问题,存在回归不到位或者测试遗漏的地方,同时测试质量的高低没有客观数据可量化。


通过单测方法补充,可以提前发现一部分问题,减少问题解决的成本,但是由于业务形态的原因, 需求变更频繁,功能迭代快,补充和维护单测的成本比较高, 在业务方的大部分前端工程中暂时没有单测方法,因此开发在自测时, 感知比较薄弱,无量化数据, 在项目提测前也没有统一指标可以把关,测试对开发的自测状况也不了解。


同时前端缺少像 jacoco 这样的集成测试覆盖率统计框架,无法通过集成测试收集覆盖率,对于测试阶段的质量仍然没有数据量化。


结合上面说的几点,我们提出了前端集成测试覆盖率统计工具的需要,以此来提升开发自测质量以及项目提测质量,同时帮助补充回归不到位或测试遗漏的场景,提升上线质量。

一、技术选型

首先,覆盖率收集的前提,需要完成代码插桩工作,插桩方法来自于两个开源覆盖率统计框架,istanbul.js 以及 istanbul-middleware (以下称 im),提供了若干个插桩方法,而 im 其实也是在 istanbul.js 的基础上做了封装, 能力来自于 istanbul-lib-instrument


所有的插桩方法,大致分为两种类型:


  • 运行前插桩

  • 运行时插桩

1.1 运行前插桩

nyc instrument


针对编译之后的 JS 文件 , 进行手动插桩 , 形成插桩后的新 JS 文件。


babel-plugin-istanbul


istanbul 提供的 babel 插件 , 能够在代码编译打包阶段直接植入插桩代码。适用于使用 babel 的前端工程,基于 react 和 vue 的工程都可以。

1.2 运行时插桩

im.hookLoader:适用于服务端的文件挂载 比如 node 应用。


当应用启动时,会在 require 入口处添加 hook 方法,使得应用启动时加载到的都是插桩后的代码。


im.createClientHandler:适用于客户端的 JS 挂载,比如 react 和 vue 的 js。


通过指定 root 路径,会把所有该路径的 js 文件请求拦截,返回插桩后的代码,即浏览器请求静态资源的动作。效果与 babel-plugin-istanbul 类似,区别在于该方法是在浏览器请求 js 时才会返回插桩代码,是一个动态过程。


插桩方式功能优势劣势
nyc本地手动插桩源js文件, 生成插桩后文件编译后的js都可手动插桩, 不限工程框架手动插桩后的文件需要自己上传, 对原打包发布流程有影响; 不适用于服务端插桩
babel-plugin-istanbul在babel编译时 , 自动生成插桩代码改造成本低 , 自动插桩快捷限定于使用babel的工程
im.hookLoaderrequire入口处添加钩子方法,返回已插桩代码改造成本低 , 自动插桩快捷仅适用于服务端插桩
im.createClientHandler拦截浏览器请求静态资源文件的GET方法, 返回插桩后的JS自动插桩 , 无须改造原打包流程和脚本仅适用于客户端插桩; 该方法基于express, 限定于使用express的工程


最后我们所使用的插桩方法


App(node)—— istanbulMiddleware.hookLoader


Client(react & vue)—— babel-plugin-istanbul

二、模块设计

主要分为三个模块,先通过代码插桩获得可追踪的代码,然后实时上报用户行为产生的代码行覆盖记录,最后呈现覆盖率相关信息。


2.1 代码插桩

Client 端:使用 babel-plugin-istanbul 插件,在 babel 编译阶段即可完成。


Node 端:依赖 istanbuljs 提供的能力 - istanbul-lib-hook 、istanbul-lib-instrument


重写 istanbulMiddleware.hookLoader 方法,node 启动前挂载文件,会在 require 方法前增加钩子函数,增加代码插桩。


插桩结果举例




被插桩的 JS 会新增一个 coverage 方法,维护并指向覆盖率信息归属,并用来获取该文件的覆盖率信息。


同时该 JS 中的方法在执行过程的路径上会留下标记,被执行到之后实时更新覆盖率信息中相对应的行或者块信息。

2.2 数据上报

Node 端:应用发布时,写入对应的工程和分支信息,创建定时器,实时上传_global.coverage 变量,即覆盖率信息。


Client 端:客户端的上报比较特殊,客户端不像服务端,在发布后可以全局保持 coverage 变量以及定时器方法,client 端所有的数据生成和消耗都跟随页面的生命周期,所以不太可控,因此需要一个额外容器进行处理,我们选择了通过 chrome 插件来上报,通过全局管理覆盖率信息对象,以及通知下发来实现上报流程。该插件详细的工作流程如下:




覆盖率服务端


  • 继承 istanbul middleware 的功能

  • 支持分支维度接收和查询覆盖率

  • 代码变更时覆盖率替换, 支持存储和查看历史版本


主要基于 istanbul-middleware 做了二次开发,扩展了 istanbulMiddleware.createHandler 方法:



/:ns/:repo /:ns/:repo/show


两个覆盖率展示接口,新增了 ns、repo、branch 三个入参,用来区别不同的覆盖率


同时增加额外参数 history 传入该变量,标志获取的是历史覆盖率。


/client/:ns/:repo?branch={}&source={} body


携带覆盖率信息,根据应用和分支信息上报,接收到上报信息之后,会先获取该分支下的已有覆盖率,然后和此次上报的信息做合并。


合并是根据文件名字遍历合并的。如果发现某个文件新旧两份覆盖率结构不同,即发生了代码变更,则会丢弃旧的覆盖率,以新覆盖率为准,同时把旧的覆盖率存储到历史版本中。

2.3 页面展示

全量覆盖率展示:使用 istanbulmiddle 原生报告生成。


增量覆盖率展示:通过 gitlab 接口对比 master 差异,分文件展示各自的覆盖率,同全量覆盖率,只是细化了,整体页面用 vue + muse-ui 完成。



以 master 分支为基准, 增量文件覆盖率



全量文件覆盖率目录结构

三、工作流程


主要分为 3 部分:对应上一节说的接入 、上报 、展示。


通过 babel 插件完成客户端代码插桩,提供给 node 端使用的插桩插件,可以一步完成服务端的代码插桩以及定时上报功能。


配合提供的 chrome 插件,完成客户端的覆盖率上报任务。


覆盖率服务端负责信息的接收和存储,并返回给前端数据信息。


前端负责数据信息展示。

四、业务实践

接入测试环境发布平台,实现以应用和分支维度的多版本实时覆盖率收集和展示功能,无缝对接项目测试环境,项目中各应用发布后,自动开启覆盖率上报,在项目测试过程中实时记录,可实时查看。在项目提测前,给予开发量化指标,项目测试结束后可以给出最终覆盖率数据,帮助测试同学检查以及完善未覆盖的功能。


目前在电商教育和行业两条业务线中已有接入,由于该工具限制在 qa 环境使用,仅限收集在 qa 环境测试的项目数据。 在功能测试阶段,从使用数据上来看,增量行代码覆盖率达到 80%以上(目前的增量只到文件维度 ,未到行维度),未覆盖的行主要包括四种: 异常捕获、防御性编码、非本次新增无需关心的代码以冗余代码,属于可允许的范围。


本文转载自公众号有赞 coder(ID:youzan_coder)


原文链接


https://mp.weixin.qq.com/s?__biz=MzAxOTY5MDMxNA==&mid=2455760043&idx=1&sn=cc6884ff2b87637e8d22369e6a9974b7&chksm=8c686a8ebb1fe39891cc3abe94dfb7fb2ffb74c7d3d13df45f7e9114e5ba92bde37a088ad96f&scene=27#wechat_redirect


2019-10-13 08:005892

评论

发布
暂无评论
发现更多内容

AI时代数据存储管理新挑战分论坛圆满举办

开放原子开源基金会

开源

共话 AI for Science,2023和鲸社区年度科研闭门会圆满结束

ModelWhale

人工智能 数据科学 科研 AI4S

软件测试/测试开发丨测试用例的概念、组成、优先级、设计工具

测试人

软件测试 测试开发

可视化技术:数据可视化17个常用图表

2D3D前端可视化开发

大数据 数据分析 数据可视化 数据可视化工具 可视化大屏

“Ladies In Tech 闪闪发光的她”分论坛圆满举办

开放原子开源基金会

开源

文心一言专业版年卡来啦!

飞桨PaddlePaddle

人工智能 文心一言

openEuler Code Camp圆满举办

开放原子开源基金会

开源

【低代码】低代码平台协同&敏捷场景下的并行开发解决方案探索 | 京东云技术团队

京东科技开发者

敏捷 低代码 并行开发

铜锁/Tongsuo项目管理委员会成立,重磅发布8.4.0版本

开放原子开源基金会

开源

优测云服务平台|总结Android开发常见风险及解决方案

优测云服务平台

风险 Android开发 Android解决方案

开源工业物联网大数据分论坛圆满举办

开放原子开源基金会

开源

企业门户平台:八项必备功能助力业务升级

天津汇柏科技有限公司

网站 企业

什么是3D模型LOD:细节级别

3D建模设计

3D渲染 材质纹理贴图 3D材质编辑

业务全面重塑,“人”要如何重塑?

用友BIP

人才管理

2023开放原子开发者大会:赋予开发者高光时刻 推进开源生态健康发展

开放原子开源基金会

开源

PON网络应用场景

小齐写代码

星河创新,产业引领:大模型引领的企业智能化升级创新实践

飞桨PaddlePaddle

人工智能 深度学习 开发者 WAVE SUMMIT

3D 纹理贴图基础知识

3D建模设计

3D渲染 材质纹理贴图 3D材质编辑

什么是多边形网格以及如何编辑它?

3D建模设计

3D渲染 材质纹理贴图 3D材质编辑

大模型热的冷思考

用友BIP

企业服务大模型

六步走向无忧,华为云数据库高可用的秘密武器

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟

如何使用不同的纹理贴图制作逼真的 3D 图形?

3D建模设计

3D渲染 材质纹理贴图 3D材质编辑

稳定的数据云平台如何炼成?奇点云解读“RAS”典型问题

奇点云

奇点云 数据云平台 DataSimba

为啥不建议用BeanUtils.copyProperties拷贝数据 | 京东云技术团队

京东科技开发者

spring BeanUtils copyProperties

软件测试/测试开发丨Bug概念,定义,判定标准,严重程度,优先级

测试人

软件测试 测试开发

从被动到主动,智能招聘为企业人效提升给出最优解

用友BIP

招聘

微服务广播模式实践:维护内存数据的缓存一致性

华为云开发者联盟

微服务 云原生 后端 华为云 华为云开发者联盟

七分技术、三分管理,做好供应链管理的需求预测

用友BIP

供应链

All in One, 快速搭建端到端可观测体系

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 华为云可观测监控大屏

前端精准测试探索:覆盖率实时统计工具_语言 & 开发_郑凌峰_InfoQ精选文章