阿里QA导读:随着业务规模的增长,服务端的架构和功能趋近复杂化,代码变更上线也越来越快,面对需要快速上线的功能,测试资源无法参与每个变更的交付过程,变更要不要测、要怎么测?成为服务端交付质量和效率最关键问题,为此,优酷质量保障团队开始了服务端精准测试的探索,经过半年的技术沉淀和体系搭建,形成了具备变更内容识别、变更影响分析、测试能力推荐、测试覆盖评估的精准测试体系。
一、"要不要测、要怎么测?"引发的思考
随着优酷业务规模的增长,服务端的架构和功能趋近复杂化,代码变更上线也越来越快,面对需要快速上线的功能,测试资源无法参与每个变更的交付过程,变更要不要测、要怎么测?成为服务端交付质量和效率最关键问题:
变更要不要测试?
- 这次变更代码有多少是空行、多少是注释、多少是有效代码,是不是对原有代码逻辑产生了影响?
- 这次变更方法是新增还是修改,变更方法的圈复杂度高不高、代码耦合度高不高,是不是线上热度调用方法?
变更要怎么测试?
- 这次变更影响了哪些业务逻辑、代码链路,是否要做接口全量回归测试?
- 要能完整覆盖这次变更影响的业务逻辑、代码链路,需要执行哪些测试用例?
面对这些问题,仅靠开发的提测文档和常规的代码分析,很难给出准确答案。为此,优酷质量保障团队开始了服务端精准测试的探索,经过半年的技术沉淀和体系搭建,形成了具备变更内容识别、变更影响分析、测试能力推荐、测试覆盖评估的精准测试体系。
二、基于代码链路分析的精准测试体系
精准测试本质上是一种基于变更分析的测试决策和评估的过程,要做好这个过程中,需要能准确的回答下面这个问题:
”变更了什么内容、产生了什么影响、需要做哪些测试、变更覆盖够不够?“
从问题可以看到,变更内容、影响对象的定义是精准测试体系的基石,直接决定需要识别的变更对象和需要评估的影响对象,并基于识别、评估结论推荐相关测试用例,以及最终评估测试活动的覆盖率。通过参考业界已有方案,也结合优酷的业务特性,我们最终确定了优酷精准测试体系的探索方向:基于代码调用链路分析的精准测试体系。用一句话描述:
以应用Java方法为观测对象,通过静态分析识别变更的Java方法,通过动态采集获取线上Java方法调用链路,然后基于代码知识库的方法匹配,精准分析变更影响的Java方法调用链路,并基于影响的链路推荐测试流量,评估测试覆盖率的测试体系
在此,特别说明一下应用Java方法调用链路的定义:是指业务流量在应用内部处理过程中,产生的完整Java方法调用栈。我们认为,相比外部子调用链路,Java方法调用链路更能代表业务场景和代码逻辑,作为变更影响、测试覆盖率评估对象,具有更高的业务价值。
2.1 实现方案
为了实现通过变更内容识别变更方法,通过变更方法分析影响代码链路,通过影响的代码链路推业务流量作为回归测试用例,既需要静态代码分析能力,能准确识别和分析变更内容。还需要能动态采集业务流量的请求参数、返回结果,代码调用链路。然后以方法为核心对象,准确建立变更内容、代码方法、调用链路、业务入口、业务流量的关联关系:
2.2 数据中心
主要是对静态代码分析数据、动态流量采集数据做结构化存储,包括主干代码知识库、变更代码知识库、流量知识库。
- 主干代码知识库
对应用主干代码做静态分析,获取应用全量方法的结构化信息,包括:方法签名、方法修饰、方法注解、入参类型、返回类型、圈复杂度、耦合度。主干代码知识库定义了精准测试体系需要的全部观测对象(应用代码的Java方法),将作为后续变更方法匹配、变更方法风险评估、代码链路采集方法筛选的统一知识库
- 变更代码知识库
对变更分支代码做静态分析,获取变更代码的结构化信息,包括:变更文件、变更方法、变更代码语义。首先通过变更代码语义分析,能准确识别变更代码行是空行、注释、日志打印、逻辑判断,还是变量操作,从而计算有效变更代码行数。然后通过匹配主干代码知识库,获取变更方法在代码知识库的唯一ID,为后续变更影响分析和变更风险评估建立方法关联关系
2.3 决策引擎
决策引擎对代码知识库、流量知识库的做变更方法匹配和链路聚合分析,从而提供变更方法风险决策、变更链路测试用例推荐、测试覆盖率评估能力
- 代码链路分析
通过聚合分析应用过去一周的线上流量,可以获取应用的全部代码调用链路,然后通过匹配主干代码知识库,获取链路上每个方法的知识库ID,最后以图形结构(点、边)对调用链路做结构化存储,从而可以实时计算每条链路的长度、深度、热度,以及从应用、入口、链路等维度,计算方法热度、调用热度
三、核心能力解决方案
借助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.1 落地效果
通过升级优酷应用部署流程,可以支持在"测试准入"阶段对构建产物实时分析,在”提交测试“阶段提供变更分析结果和测试用例推荐,从而在无需人工介入的情况下,实现应用无感接入优酷精准测试体系。