通用技术 精准测试中的一些疑问?

勇伢子 · 2021年10月27日 · 最后由 勇伢子 回复于 2021年10月29日 · 5231 次阅读

最近基于 javaParser ,也算是做了一部分扫描调用链的工作,但是实际用起来的时候,发现回溯上游调用的时候,最终得出来的调用链实际会很多。里面会有一些无关的调用。比如我虽然 A 调用了 B,但是只是某个逻辑判断下才会去调 B,当然这是需要动态执行的时候才知道的。
1、请问大家如何处理这种无关调用的?
2、我也有实现根据差异代码,获取改动方法的调用链,那么如何结合覆盖率数据,去判断这条调用链有覆盖?
3、运行期才出现的、通过反射等方式的调用大家是怎么分析调用的。

共收到 14 条回复 时间 点赞

1、A 的某个判断里调用了 B,那么为什么是无关调用?这就是 B 的影响面
2、将增量代码扩展至这条调用链里的方法

1、楼主这个回溯上游调用,我理解和 idea 自带的 find usages 其实是类似的方式?如果是,那通过静态分析获取调用关系。这个原理上就无法准确到你例子说的 if else 程度,毕竟并非运行时的话,没人知道是否走到调用 B 的逻辑,那宁滥勿缺,肯定要把这条调用链带上。

2、不知道增量代码覆盖率数据,即直接统计有改动的代码对应行是否又被覆盖,是不是可以满足?或者可以把你这里的 “调用链” 举个具体的代码例子说明下,你的调用链定义具体是什么?从有足够细节的定义去扩展,会比从 “调用链” 这个名字去扩展要方便很多。

  1. 我理解去不了所谓的【无关调用】,你想在静态分析技术中处理动态运行存在的问题,看着有点玄幻。要不就是你本身已经具备先验知识,比如你事先知道要关注的调用链上游会包含什么因素,那你就只关注这条子调用链即可,其他的不管。
  2. 要判断【这条调用链有覆盖】,换个说法就是判断【覆盖路径 是否包含 调用链】,也就是调用链是覆盖链路的子集。具体怎么搞,那就看你的数据格式是怎么样的。
陈恒捷 回复

第一点的确是这样的
第二点,我的调用链是指的服务入口方法到改动方法的链路。其实这个问题可以换个说法:分析出来的这条链路如何定义它是有被覆盖的。

王稀饭 回复

是的,覆盖路径指的是通过 jacoco 或者其他方式,拿到这个链路路径上每个节点的覆盖情况,都有覆盖就是覆盖的意思?

勇伢子 回复

举个例子,比如说你的增量调用链最后是 B->C->D,你通过覆盖率拿到你测试后的调用链是 A->B->C->D->E->F ,这样不就能理解你的的测试已经覆盖了你的增量链路么? 也就是判断子集的操作

勇伢子 回复

首先,我理解你的链路每个节点,具象到代码层面,应该就是每个函数的入口了吧。那确认链路是否有被覆盖,你得用会记录每个函数入口信息组合的链路跟踪工具(比如一些服务端 APM 工具),记录每个从服务入口进来后的链路。

代码覆盖率工具一般关注的只是是否覆盖这个结果,不关注通过什么链路覆盖这个过程,也不会记录这种信息。

运行期才出现的、通过反射等方式的调用大家是怎么分析调用的。

前面忘了回答,这种原理上就无法通过静态分析来做了,只能通过运行时的动态调用链路记录来做,而且没法保障是否全(没跑到就不会被记录),只能作为补充。

  • 1、精准测试的前提是被测代码干净,if else 拿来做少量逻辑控制是可以的,拿来做场景分支控制就是屎山代码,这种你首先应该解决的是单测的问题,而不是精准测试这种宏观层面的手段。
  • 2、能够识别调用链就不错了,已经可以减少很多无关测试,你把这一步做好再考虑后面的问题比较实际一点,再迈一步就不是测试团队自己能够解决的了。
槽神 回复

是的,并且精准始终也无法做到全部调用都查到,不过可以减少很大一部分无关的回归

陈恒捷 回复

我的做法是通过实时获取这个工程的行覆盖数据,如果我扫出来的调用链上的每个节点的对应代码行是覆盖了的,那这个节点就是覆盖了。

勇伢子 回复

从严格意义上说,这种不能反推调用链就覆盖到了,也可能实际这几个节点是在好几个调用链里分别覆盖到的,不是真的有走过一条直接就是这几个节点的调用链

不过从工程角度,要真的那么细成本很高也很难,做到这个也足够了。

如果加上 asm 对 class 进行遍历 visit 那是可以找到更准确的对应的调用链路。ast 解析后,再通过一些手段拿到 signature,和 asm 的分析组合使用,应该能解决大部分遇到的难题。

树叶小记 回复

回头研究下

勇伢子 关闭了讨论 10月29日 14:14
勇伢子 重新开启了讨论 10月29日 14:14
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册