背景
随着业务增长, 随之而来的前端需求激增, 如何在有限的时间内保证前端代码的质量. 通过测试同学单方面的保障, 还是免不了前端线上问题, 存在回归不到位或者测试遗漏的地方, 同时测试质量的高低没有客观数据可量化。
通过单测方法补充, 可以提前发现一部分问题, 减少问题解决的成本, 但是由于业务形态的原因, 需求变更频繁, 功能迭代快, 补充和维护单测的成本比较高, 在业务方的大部分前端工程中暂时没有单测方法, 因此开发在自测时, 感知比较薄弱, 无量化数据, 在项目提测前也没有统一指标可以把关, 测试对开发的自测状况也不了解。
同时前端缺少像jacoco这样的集成测试覆盖率统计框架, 无法通过集成测试收集覆盖率, 对于测试阶段的质量仍然没有数据量化 结合上面说的几点, 我们提出了前端集成测试覆盖率统计工具的需要, 以此来提升开发自测质量以及项目提测质量, 同时帮助补充回归不到位或测试遗漏的场景, 提升上线质量。
技术选型
首先, 覆盖率收集的前提, 需要完成代码插桩工作, 插桩方法来自于两个开源覆盖率统计框架, istanbul.js以及istanbul-middleware (以下称im) , 提供了若干个插桩方法, 而im其实也是在istanbul.js的基础上做了封装, 能力来自于istanbul-lib-instrument 所有的插桩方法, 大致分为两种类型 —— 1、运行前插桩 2、运行时插桩。
运行前插桩
nyc instrument
针对编译之后的JS文件 , 进行手动插桩 , 形成插桩后的新JS文件。
babel-plugin-istanbul
istanbul提供的babel插件 , 能够在代码编译打包阶段直接植入插桩代码。
适用于使用babel的前端工程,基于react和vue的工程都可以。
运行时插桩
im.hookLoader
适用于服务端的文件挂载 比如node应用 当应用启动时 , 会在require入口处添加hook方法 , 使得应用启动时加载到的都是插桩后的代码。
im.createClientHandler
适用于客户端的JS挂载 ,比如react和vue的js 通过指定root路径,会把所有该路径的js文件请求拦截,返回插桩后的代码,即浏览器请求静态资源的动作 效果与babel-plugin-istanbul类似,区别在于该方法是在浏览器请求js时才会返回插桩代码,是一个动态过程:
最后我们所使用的插桩方法 App(node)—— istanbulMiddleware.hookLoader
Client(react & vue)—— babel-plugin-istanbul
模块设计
主要分为三个模块 , 先通过代码插桩获得可追踪的代码 , 然后实时上报用户行为产生的代码行覆盖记录 , 最后呈现覆盖率相关信息.
代码插桩
Client端
使用babel-plugin-istanbul插件, 在babel编译阶段即可完成
Node端
依赖istanbuljs提供的能力 - istanbul-lib-hook 、istanbul-lib-instrument 重写istanbulMiddleware.hookLoader方法 , node启动前挂载文件 , 会在require方法前增加钩子函数, 增加代码插桩
插桩结果举例
被插桩的JS 会新增一个coverage方法, 维护并指向覆盖率信息归属, 并用来获取该文件的覆盖率信息 同时该js中的方法在执行过程的路径上会留下标记, 被执行到之后实时更新覆盖率信息中相对应的行或者块信息。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理