代码覆盖率之链路覆盖率前端设计

一、前言
二、先别急着写代码:搞懂真正的需求
三、 第一次尝试:用 Echarts 画,结果 “翻车” 了
3.1 树图的尝试
3.2 Graph的尝试
3.3 力引导布局的尝试
四、第二次尝试:换 Ant Design Charts,又栽了
五、终选方案:用 AntV G6,终于摸到门道
5.1 解决第一个问题:让 1000 个节点跑起来
5.2 解决第二个问题:让节点自动排得整整齐齐
5.3 解决第三个问题:让交互体验流畅自然
六、总结
6.1 从试错中提炼的技术实践
6.2 未来计划

一、前言
在日常开发测试中,代码覆盖率是衡量测试完整性的核心指标。那现有的代码行级别覆盖率工具(如下图)是不行了么,为什么还要做链路覆盖率功能?
代码行级别覆盖率工具
代码行级别覆盖率工具
并非行覆盖率功能不足,而是链路有其独特定位:用于查看接口的调用链路,展示涉及文件的覆盖情况,是流量回放的辅助分析工具。实现效果如下图:
链路覆盖率工具
链路覆盖率工具
回顾产品对此功能的前端设计,需求可概括为:
能清晰展示函数的调用关系
要一眼看清覆盖效果,点击能查看具体信息
当然功能越多越好!
其他看着发挥吧~
既然产品要求灵活发挥,那就该着手行动了。
但,先别急着写代码。
二、先别急着写代码:搞懂真正的需求
起初我想当然地认为:不就是绘制流程图吗?用 Echarts 画几个节点连线就行。
但真正上手才发现,需求远不止 “画几个节点连线” 这么简单:
要呈现整个系统的函数调用网络,而非零散的节点
要能直观体现函数覆盖情况,快速定位目标函数
点击、鼠标悬浮函数节点,展示不同的覆盖信息
这三个需求翻译过来就是:
如何处理大规模数据(性能问题)
如何让节点自动整齐排列(布局问题)
如何让用户顺畅操作图表(交互问题)
带着这三个问题,开始踩坑之旅。
三、 第一次尝试:用 Echarts 画,结果 “翻车” 了
首先尝试了最熟悉的 Echarts。
3.1 树图的尝试
因为接口提供的是列表数据,在根据边数据关系处理成树型结构后,发现函数调用不单单是一对多的关系。
但树图布局仅支持树型结构,无法展示多对多。这个方案还没开始就pass了。

3.2 Graph的尝试
放弃树图后,进而选择了关系图,当我看到 Graph 的示例后,表示这非常符合想要展示的效果:
series: [{
type:’graph’,
layout: ‘none’
}]

但有一个问题犯了难,Graph 的数据,需要 x, y 坐标来确定节点展示的位置。那有没有不用坐标数据,就能自动将节点完美排列出来的图形呢。
基于这个想法,又看到了力引导布局。
3.3 力引导布局的尝试
尝试力引导布局后,节点数据不用计算坐标,开发就更加简单了:
series: [{
type: ‘graph’,
layout: ‘force’, // 力导向布局
force: {
repulsion: 100 // 节点之间的排斥力
}
}]
初期效果还行,几十个节点的时候,能看出谁调用谁。但当数据量加到 500 个节点,问题出现了:
节点堆成一团,根本分不清谁连谁

显然,力引导布局仅适用于小数据量场景。
那么,Echarts Graph 做为待定方案,我又去试了试别的可视化插件,看看有没有更合适的。
四、第二次尝试:换 Ant Design Charts,又栽了
项目是基于 AntD 组件库写的,那 Ant Design Charts 不就是个专门画流程图的工具嘛,其中 FlowGraph 看起来就很专业,还能和项目的 AntD 组件库无缝衔接。

新方案的效果立竿见影:连线是带箭头的折线,节点样式也好看了。但新问题也很快出现了:
数据量大时,操作的节点更新信息后,数据重新加载,画布会重新渲染,例如打开抽屉弹窗、变更节点颜色的操作,页面响应就出现了明显的卡顿
产品想要小地图和工具栏来进行显式操作,那怎么设计去将这些功能融入图形中

如何只更新选中的节点,不重新渲染整个画布呢,带着这个问题,又做了进一步探索。
直到看到了AntV G6。
五、终选方案:用 AntV G6,终于摸到门道
经历两次选型不理想后,开始着手研究专业的图可视化引擎。当看到了AntV G6,一个写着强分析、高性能、易扩展标语的产品,那就来试试它。
5.1 解决第一个问题:让 1000 个节点跑起来
初始化配置时,特意找了 1000+ 的节点进行测试:

结果令人惊喜,使用单节点的更新方法,操作后页面完全不卡顿!拖拽、缩放等操作也很流畅。
const graph = new G6.Graph({
container: ‘container’,
layout: {
type: ‘antv-dagre’,
rankdir: ‘LR’,
ranksep: 100, // 层级间距
nodesep: 10, // 节点间距
},
// 其他配置…
});
5.2 解决第二个问题:让节点自动排得整整齐齐
之前用 Echarts 的力引导布局,节点总是乱飘,容易出现重叠缠绕的问题。G6 的专业布局算法帮了大忙:
用antv-dagre布局:函数调用链路从左到右排,一目了然
还可以调节点间距:ranksep: 100(层级间距)、nodesep: 10(节点间距)
5.3 解决第三个问题:让交互体验流畅自然
这部分是最花心思的,结合用户使用习惯,实现了几个核心交互:
1)节点高亮:
点击函数时,高亮当前节点,弹窗展示行覆盖信息

鼠标悬浮在函数节点上,前后调用路径高亮显示,并显示更详细的函数覆盖信息

// 更新节点状态
graph.updateNodeData([{ id, states: [‘selected’] }]);
// 聚焦节点,使节点在屏幕中间
graph.focusElement(id);
// 重绘图表
graph.draw();
// 自定义显示详情面板函数
showDetailPanel(id);
2)颜色编码:用颜色直观区分覆盖状态,让用户可以一眼就知道哪些函数还没被覆盖。定义的颜色规则如下:

const COVERAGE_COLORS = {
selected: ‘#fadb14’, // 黄色:当前选中的节点
full: ‘#52c41a’, // 绿色:覆盖率100%的节点
partial: ‘#1677ff’, // 蓝色:覆盖率大于0%的节点
none: ‘#f5222d’, // 红色:覆盖率0%的节点
};
const getNodeColor = (status, isSelected, isActive) => {
let baseColor = COVERAGE_COLORS[status];
if (isSelected) baseColor = COVERAGE_COLORS.selected;
// 添加透明度效果,实现鼠标悬浮时颜色高亮
const alpha = isActive ? ” : ’80’;
return baseColor + alpha;
};
3)展开/收起:当节点拥有过多子数据时,页面布局就会拉伸的过长,影响浏览效率。通过控制节点和边的显示与隐藏状态,用户可以聚焦关注的部分:

const { edges, nodes } = graph.getData();
// 获取所有子孙节点
const nodeList = getDescendants(nodeId);
// 子节点增加显示隐藏状态
nodes.forEach((node) => {
if (nodeList.includes(node.id)) {
onCollapseNode({ nodeId: node.id, type: ‘node’ });
}
});
// 子边增加显示隐藏状态
edges.forEach((node) => {
const endId = node.target;
if (nodeList.includes(endId)) {
onCollapseNode({ nodeId: node.id, type: ‘edge’ });
}
});
const onCollapseNode = ({ type = ”, nodeId = ” }) => {
//处理显示隐藏逻辑,将选择节点及其子节点状态取反
};
4)扩展功能:增加拖拽、放大、缩小、刷新、信息提示窗等功能,用户体验直接拉满:
const graph = new G6.Graph({
behaviors: [
‘drag-canvas’,
‘zoom-canvas’,
{ type: ‘hover-activate’, degree: 1 },//路径高亮追踪
],
plugins: [{
type: ‘minimap’,//迷你图
}, {
type: ‘toolbar’,//工具栏
}, {
type: ‘tooltip’,// 提示窗
}]
});
六、总结
6.1 从试错中提炼的技术实践
从三次技术尝试的过程来看,初期对插件的选型都基于工具的基础特性,缺乏系统性调研,导致在实际开发中暴露了诸多问题,基于这些实践,总结经验如下:
充分调研:技术选型前需通过多维度调研明确工具边界:
内部调研:梳理团队现有技术栈、成员对工具的熟悉度、历史项目中类似场景的解决方案,避免重复踩坑;
外部调研:查阅工具官方文档、社区 issue、第三方测评,明确工具的适用场景与短板;
直接咨询:向有经验的同学请教实际开发中的坑点,获取一手实践经验,快速缩小选型范围。
不迷信“万能工具”:不同工具的设计目标存在差异,技术选型的核心是让工具特性与场景需求精准匹配,而非依赖个人熟练度。
性能优先于功能:对于复杂图场景,性能是用户体验的基石:
需优先通过技术选型确保页面流畅,再逐步叠加交互功能。若前期忽视性能,即使功能完备,也会因卡顿导致工具不可用。
6.2 未来计划
将链路覆盖率和日常代码变更结合起来
每次代码提交时,团队通常会对变更部分进行针对性测试。如果能够将链路覆盖率与这些代码变更进行关联分析,就可以精准识别出受影响的调用路径,计算增加变更链路覆盖的情况,帮助团队更好地评估代码变更的风险。

如果你也在做类似的可视化需求,欢迎相互交流~
作者: 刘筱雨 转转测试开发工程师

想了解更多转转公司的业务实践,点击关注下方的公众号吧!

声明:来自转转QA,仅代表创作者观点。链接:https://eyangzhen.com/2616.html

转转QA的头像转转QA

相关推荐

关注我们
关注我们
购买服务
购买服务
返回顶部