基于代码链路分析的精准测试体系
转载:https://mp.weixin.qq.com/s/aik3CetmoOvP1jSHqGODiQ
1. "要不要测、要怎么测?"引发的思考
随着优酷业务规模的增长,服务端的架构和功能趋近复杂化,代码变更上线也越来越快,面对需要快速上线的功能,测试资源无法参与每个变更的交付过程,变更要不要测、要怎么测?成为服务端交付质量和效率最关键问题:
变更要不要测试?
- 这次变更代码有多少是空行、多少是注释、多少是有效代码,是不是对原有代码逻辑产生了影响?
- 这次变更方法是新增还是修改,变更方法的圈复杂度高不高、代码耦合度高不高,是不是线上热度调用方法?
变更要怎么测试?
- 这次变更影响了哪些业务逻辑、代码链路,是否要做接口全量回归测试?
- 要能完整覆盖这次变更影响的业务逻辑、代码链路,需要执行哪些测试用例?
面对这些问题,仅靠开发的提测文档和常规的代码分析,很难给出准确答案。为此,优酷质量保障团队开始了服务端精准测试的探索,经过半年的技术沉淀和体系搭建,形成了具备变更内容识别、变更影响分析、测试能力推荐、测试覆盖评估的精准测试体系。
2. 基于代码链路分析的精准测试体系
精准测试本质上是一种基于变更分析的测试决策和评估的过程,要做好这个过程中,需要能准确的回答下面这个问题:”变更了什么内容、产生了什么影响、需要做哪些测试、变更覆盖够不够?“从问题可以看到,变更内容、影响对象的定义是精准测试体系的基石,直接决定需要识别的变更对象和需要评估的影响对象,并基于识别、评估结论推荐相关测试用例,以及最终评估测试活动的覆盖率。通过参考业界已有方案,也结合优酷的业务特性,我们最终确定了优酷精准测试体系的探索方向:基于代码调用链路分析的精准测试体系。用一句话描述:以应用Java方法为观测对象,通过静态分析识别变更的Java方法,通过动态采集获取线上Java方法调用链路,然后基于代码知识库的方法匹配,精准分析变更影响的Java方法调用链路,并基于影响的链路推荐测试流量,评估测试覆盖率的测试体系在此,特别说明一下应用Java方法调用链路的定义:是指业务流量在应用内部处理过程中,产生的完整Java方法调用栈。我们认为,相比外部子调用链路,Java方法调用链路更能代表业务场景和代码逻辑,作为变更影响、测试覆盖率评估对象,具有更高的业务价值。
2.1 实现方案
为了实现通过变更内容识别变更方法,通过变更方法分析影响代码链路,通过影响的代码链路推业务流量作为回归测试用例,既需要静态代码分析能力,能准确识别和分析变更内容。还需要能动态采集业务流量的请求参数、返回结果,代码调用链路。然后以方法为核心对象,准确建立变更内容、代码方法、调用链路、业务入口、业务流量的关联关系:基于不重复造轮子的原则,我们选择通过蚂蚁的Sparrow做静态代码分析,通过集团的Sandbox做动态流量采集,在此基础上通过构建数据中心、决策引擎实现精准测试体系的支撑能力,并且通过平台化提供给业务团队接入使用。方案的整体架构如下:
2.2 数据中心
主要是对静态代码分析数据、动态流量采集数据做结构化存储,包括主干代码知识库、变更代码知识库、流量知识库。
- 主干代码知识库
对应用主干代码做静态分析,获取应用全量方法的结构化信息,包括:方法签名、方法修饰、方法注解、入参类型、返回类型、圈复杂度、耦合度。主干代码知识库定义了精准测试体系需要的全部观测对象(应用代码的Java方法),将作为后续变更方法匹配、变更方法风险评估、代码链路采集方法筛选的统一知识库
变更代码知识库
对变更分支代码做静态分析,获取变更代码的结构化信息,包括:变更文件、变更方法、变更代码语义。首先通过变更代码语义分析,能准确识别变更代码行是空行、注释、日志打印、逻辑判断,还是变量操作,从而计算有效变更代码行数。然后通过匹配主干代码知识库,获取变更方法在代码知识库的唯一ID,为后续变更影响分析和变更风险评估建立方法关联关系
- 流量知识库
动态采集业务入口的线上实时流量、线下测试流量,包括请求参数、返回结果、代码调用链路。为了获取业务入口完整的代码调用链路,需要给Sandbox配置需要采集的Java方法,为此,我们首先定义了应用核心方法模型,然后通过匹配主干代码知识库,可以实时分析出需要采集的核心方法,最后通过Sandbox对这些方法插桩和采集,从而获取到流量进入应用内部后的完整代码调用链路,如下图:
2.3 决策引擎
决策引擎对代码知识库、流量知识库的做变更方法匹配和链路聚合分析,从而提供变更方法风险决策、变更链路测试用例推荐、测试覆盖率评估能力
- 代码链路分析
通过聚合分析应用过去一周的线上流量,可以获取应用的全部代码调用链路,然后通过匹配主干代码知识库,获取链路上每个方法的知识库ID,最后以图形结构(点、边)对调用链路做结构化存储,从而可以实时计算每条链路的长度、深度、热度,以及从应用、入口、链路等维度,计算方法热度、调用热度
- 变更风险决策
以变更方法为分析对象,基于代码知识库,可以获取变更方法是否为有效代码变更,以及变更方法的圈复杂度、代码耦合度等静态分析数据。再基于代码链路分析结果,可以实时获取变更方法影响的代码链路、链路热度、方法热度、调用热度等动态采集数据。从而可以实现精准评估变更方法的风险等级和实际影响对象。为此,我们建立了以下变更风险评估模型:
其中:M(r)为方法变更风险值、M(c)为方法圈复杂度、M(e)为方法代码耦合度、M(c,h)为方法影响链路的热度、M(h)为变更方法热度
- 测试用例推荐
基于线上代码链路聚合分析结果,可以建立业务流量和代码调用链路的关联关系,再基于变更方法影响的代码调用链路,就可以分析出变更影响链路对应的全部业务流量,从而实现基于代码链路影响的测试用例推荐
(如上图所示,将为代码变更1推荐业务流量1、业务流量2,这些业务流量会被自动推荐给智能回放、自动化测试等回归测试任务)
2.4 平台能力
借助优酷服务端研发效能平台,我们将精准测试体系完备的基础能力和海量数据化繁为简,可以为业务同学提供更直观的变更分析、场景分析、链路分析,以及通过智能回放、自动化测试提供更高效精准的回归测试能力。以下对部分核心功能做简单说明和展示:
- 变更分析
对Aone线下部署流程的每次构建做增量代码分析,提供代码变更内容、代码变更影响面的展示和分析
- 场景分析
通过对业务入口的请求参数、返回结果建立业务特征,可以对采集到的全部业务流量做聚合分析,提供业务场景的特征组合结果、热度的展示和分析
- 链路分析
通过建立代码调用链路特征标识,可以对采集到的全部代码调用链路做聚合分析,提供代码调用链路热度、完整调用栈的展示和分析
- 智能回放、自动化测试
将变更方法影响链路的业务流量推荐给智能回放、自动化测试等回归测试任务,提供精准回归测试能力,实现变更链路100%测试覆盖
3. 核心能力解决方案
借助Sandbox、Sparrow提供的基础能力,虽然可以快速实现静态代码分析和动态流量采集,但在实际落地过程中,还是遇到了很多基础能力之外的技术挑战,比如:
- 由于采集机异常下线、采集限流等问题,导致采集流量无法有效覆盖线上实际流量模型,导致应用代码调用链路不完备
- 由于人工配置采集方法的差异性,导致无业务意义方法(get\set等)被采集,而关键链路上的方法没有采集,导致代码调用链路不完整
- 静态代码分析可以获取变更文件、类、方法、代码行信息,但不知道变更代码语义,无法准确识别变更有效性,导致变更分析不准确
为此,在Sparrow、Sandbox基础能力之上,优酷自研了流量采集智能调度、应用核心方法自动解析、变更代码语义精准识别等创新解决方案,不仅保障了代码调用链路采集完备性、提升了变更方法分析准确性,也实现了在无需人工介入的情况下,优酷服务端大规模接入精准测试体系。
3.1 代码调用链路采集完备性
要获取应用完备的代码调用链路,需要具备2个前提:采集流量有效覆盖7*24小时全部时间段、采集方法有效覆盖应用全部核心方法。
- 流量采集智能调度
要能采集应用线上全部代码调用链路,就要保障采集流量的完备性,采集流量能有效覆盖业务全天流量模型。为此,我们首先构建了采集模块自动运维的能力,应用接入火影后,平台会实时监测采集机状态,一旦发现采集模块异常下线(应用弹性缩容、机器异常等原因),会再实时激活一台采集机,从而保障采集模块7*24小时在线。然后还构建了采集配置智能调度能力,我们将一天分为48个采集调度窗口,每个调度窗口会根据入口当天入库流量数、当前窗口入库流量数,自动调整下个采集窗口的采集白名单和采样率,从而不仅可以保障采集流量能覆盖全天各个时间段,也有效解决了高QPS接口采集过量,低QPS接口采集不到流量的情况。整个过程完全由平台自动调度,不仅极大降低了业务团队采集模块、采集配置的维护成本,也提升了采集效率和质量。
应用核心方法自动解析
Sandbox采集代码调用链路,需要配置采集方法列表,这个对业务团队接入提出了很大挑战,配置方法太多,会导致采集链路过于复杂、无业务意义的链路噪音比较多,极大增加了变更分析成本。配置方法太少,会导致采集链路过于简单,无法体现完备的代码逻辑和业务场景。这些问题都让精准测试体系变的不那么”精、准“。为此,我们通过静态代码分析,构建了应用代码全量方法知识库,结构化存储了类、方法的全部基础信息,然后通过建立核心方法模型:接口类的实现方法 + 圈复杂度大于5的方法 + 代码耦合度大于0方法,实现了应用核心方法自动解析能力。相比人工配置采集方法,代码调用链路完备性提升了50%(基于链路深度、链路长度做对比),变更方法采集率从30%提升到90%,保障了绝大多数变更方法都能分析出链路影响面。
3.2 变更代码语义精准识别
传统静态代码分析可以知道变更文件、类、方法、代码行等信息,基于这些信息分析出来的变更方法通常会比较多,但可能变更方法只是加了一些注解,或者减少了一些空行,这些方法变更并不影响代码业务逻辑,并不需要测试关注。因此,要能准确识别变更有效性和风险,除了需要知道变更多了行,还需要知道变更代码什么内容。为此我们借助Sparrow变更代码语义分析能力,通过获取变更代码完整的ast语义结构,能有效识别变更代码是否是空行、日志、注释、变量操作、逻辑判断等,从而实现了变更方法有效性评估。相比传统静态代码分析结果,有效变更方法数量降低了30%,同时也避免了无效代码改动对变更分析准确性的影响。
4. 落地效果和未来展望
4.1 落地效果
通过升级优酷应用部署流程,可以支持在"测试准入"阶段对构建产物实时分析,在”提交测试“阶段提供变更分析结果和测试用例推荐,从而在无需人工介入的情况下,实现应用无感接入优酷精准测试体系。
并且对接了服务端提测流程,在提测单中可以直观的看到提测变更的分析结论:
4.2 未来展望
基于精准测试体系的代码知识库和变更分析能力,未来会在代码质量治理、变更免测评估上面做更多的探索:
- 代码质量治理:利用主干代码知识库和调用链路分析结果,持续治理3高(圈复杂度高、代码耦合度高、线上调用热度高)方法的代码质量,提升优酷代码健康分
- 变更免测评估:基于变更代码知识库、调用链路分析结果、测试用例推荐结果,持续优化变更风险分析模型,减少低风险变更(变更方法圈复杂度低、线上调用热度低、推荐用例覆盖率高)对测试资源的占用,提升服务端变更免测率
感谢
优酷精准测试体系依赖Sandbox、Sparrow基础能力的支持,对代码分析和流量采集有兴趣的同学可以参考:
- Sandbox:https://github.com/alibaba/jvm-sandbox
- Sparrow:https://gangfan.github.io/assets/papers/sparrow.pdf