藏经阁一种基于AOP的系统级测试解耦方案
Posted 百度QA
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了藏经阁一种基于AOP的系统级测试解耦方案相关的知识,希望对你有一定的参考价值。
☞背景☜
众所周知,根据测试分层的理论,系统级测试能够发现影响面更大的问题,同时测试成本也更大,系统级测试关联的模块数多,关注系统级别的健康情况。
伴随着系统级测试在公司内部很多复杂系统测试体系中发挥越来越重要的作用,为了提升系统级的效率和质量,测试过程中往往会把全系统拆分成多个子系统进行测试,实现子系统独立测试即为测试解耦,下面拿一个例子来说明测试解耦过程(如图1),假设全系统包含4个模块(实际使用时可以更多),那么测试人员可以分别独立测试A、A+B等子系统,也可以测试A+B+C+D这样的全系统,具体的测试拓扑完全由测试人员来根据测试场景来自由设定。
图1 测试解耦示意图
系统级测试解耦往往是由于如下几个原因:
(1) 可控性好,提升测试精准性,提升测试效率:子系统1的测试同学,测试前期只需要关注子系统1的测试情况,关注子系统1的内部问题,最后再进行全系统测试,关注整体系统的正确性。
(2) 提升测试稳定性:对其他子系统和依赖服务/数据进行mock,降低了系统之间相互干扰带来的排查代价,提升测试稳定性。
(3) 降低资源消耗:全系统大量模块(上百个)对资源消耗巨大,拆分成独立子系统后单次测试资源占用降低,测试可行性更高。
伴随着测试解耦思路的出现,系统级测试面临着新的问题:
(1) 如何高效的给被测子系统构造需要的各种依赖mock数据,满足各种场景的测试诉求,保持测试质量?
(2) 很多系统级测试(如DIFF测试、性能测试)使用线上请求来进行测试,如何构造/生成适配于线上请求的各种依赖数据,提升测试效率?
本文介绍的方案可以较好的解决这两个问题。
☞调研☜
测试领域内有很多团队在使用测试解耦方案,对解耦方案进行了梳理归类,主要分为如下3种:
方案1:基于数据/日志同步+mock的数据隔离方案(图2):适合于系统规模相对较小、数据稳定性高、日志规范性高、数据格式比较统一的只读系统,此方案有很多团队在使用,没有统一的实现方案,一般是根据业务系统的特征来进行设计实现和使用。
图2
方案2:基于netbridge/capture/tcpcopy的截包回放方案(图3):适合于大部分类型的只读系统,该方案工作在网络层,需要对协议进行适配,适合于协议类型比较集中的场景,这种方式在很多系统规模比较大的复杂检索系统在使用,且形成了比较统一规范的解决方案。
图3
方案3:基于AOP的测试解耦方案:适合于读写系统、存在较多有状态数据源、协议多且流量复制代价大的系统,该方案工作在应用层,无需进行协议适配,具体的方案本文会重点介绍。
方案3出现的背景是因为一些业务端对系统级测试需求的增强,但已有的方案1、2无法因为如下问题无法在业务系统落地使用。
(1) 读写结合:A:不同的业务场景可以拆解为不同读写接口的强耦合序列,需要保证请求之间的数据依赖关系不被破坏B:为了满足测试场景丰富的诉求,线上录制成为测试准备的首选C:因为写请求的存在,无法通过旁路方式进行录制(避免对线上数据造成影响),也不能对线上拓扑造成影响,故方案2不可行。
(2) 有状态的数据源:测试的输入和数据源(如DB)内的数据状态存在强耦合,在数据量大和数据变更频繁的情况下无法进行数据状态和请求的准确匹配,故方案1不可行。
(3) 测试代价大:典型的多入口、多出口(数百个外部依赖服务、几十种协议格式)导致协议适配代价巨大,故方案1和方案2均不可行。
☞整体方案☜
基于AOP的测试解耦方案设计之初是为了满足一些复杂业务系统的使用需求,这些业务系统具备如下特点,所以在设计上不仅满足此类业务系统的使用需求,也在设计方案上尽可能的考虑了通用化和可扩展性。
(1) 重业务、轻数据
(2) 接口多、入口参数类型丰富,属于典型的广入口、广出口架构
(3) 读请求和写请求按照业务场景结合来实现业务需求
(4) 业务模块全部为java模块
在前文中提到,系统级测试解耦一方面要关注的是测试质量,体现在具体事项上是测试数据的可用性,仿真性,另一方面要关注的是测试效率,体现在具体事项上是测试数据的管理代价,据此,把基于AOP的系统级测试解耦方案设计分为如下三个阶段:
(1) 线上数据录制:为了能够提升测试数据的覆盖面、仿真性,满足系统级测试对大数据量的诉求,采用从线上进行数据录制的方案解决数据准备问题。
(2) 数据管理:为了提升测试人员的使用便易性且满足各种业务场景对测试数据的诉求,通过数据管理服务对线上的大数据进行统一清洗、管理、筛选,让使用者可以通过平台提供的简单规则和操作来快速生成需要的测试数据,提升测试效率。
(3) 线下回放测试:根据测试场景,搭建对应测试环境拓扑,通过回放方式来完成子系统解耦,实现让用户只关注自己的子系统,完全不依赖于其他依赖服务。
整体架构如图4:
图4
整体方案具备如下特点:
(1)高效性:线上实时录制,录制过程无需人工参与;数据实时推送,分类数据管理。
(2)高仿真性:线上数据可定制抽样,与线上用户行为保持一致。
(3)稳定性:保持系统内部各个模块的出口、入口数据高度一致,保证整体测试的回放测试稳定性。
从图4可以看出,线上录制环节包含录制组件、线下回放测试环节包含回放组件,在设计和维护时常常把两个组件合并起来管理,录制回放组件是基于AOP来设计并实现的,也是本文提到的测试解耦方案的核心部分,简单介绍下AOP的原理:
AOP(Aspect OrientedProgramming)为面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,可以理解为我们动态的在代码中植入我们想要的代码,这些代码可以用来实现我们需要的录制和回放解耦的功能,使用时有几个关注点如下:
(1) 配置要动态插入代码的切面
(2) 序列化/反序列化过程
具体参见图6中的过程,序列化过程是把模块内部的对象序列化json明文并进行压缩存储,反序列的过程是把从回放集群读取到的json明文转化为对象完成测试解耦。
(3) 数据存储和管理
图5是数据录制和存储过程,首先采用线上实时抽样录制,可以通过设置不同长度的抽样窗口来控制抽样比例,然后对产出的数据进行缓存压缩和落盘,一方面可以降低对线上服务的实时影响,另一方面可以降低对存储空间的占用,最终落盘的数据会通过离线任务转存到大数据存储中。
图5
基于AOP的测试解耦方案和已有的测试解耦方案有一些比较明显的区别,可以简单的汇总如下:
1、工作在应用层,和基于netbridge等的方案(方案2)工作于网络层的不同,录制回放组件1)无需进行协议适配2)无需修改业务模块的拓扑,可以较好的适应系统读写结合的业务特点,不仅降低了维护旁路的代价,降低了对线上数据产生影响的可能,同时也没有协议适配和模块接入代价。
2、录制过程基于线上录制,和基于netbridge等的方案(方案2)使用旁路或单独环境录制不同,无需要单独维护独立环境,也无资源的额外消耗,降低了测试准备的代价。
3、录制和回放组件统一管理,使用开关控制录制/回放模块,组件可以同时工作于线上和线下,便于管理。
图6为比较典型的基于AOP的测试解耦示例,也展示测试解耦的工作过程,左侧为线上的录制过程,右侧为线下测试过程,下面通过两个不同场景来说明下该过程。
场景1:线下子系统(仅包含模块A)测试时,需要做如下几步:
1)线上录制,此步只需要接入时一次性接入,后续无需关注
2)从数据管理平台中找到子系统A的压力数据和依赖数据,即筛选A模块的所有入口数据和出口数据,这些数据上都打了A的标签,可以很方便的从平台上获取到并灌入到回放集群中。
3)把回放组件以插件形式放入到被测试模块A中,把开启回放模式,启动模块A
4)启动测试驱动工具,并把A的入口数据作为驱动工具的数据输入,开始测试
5)对测试结果进行分析、对比形成测试报告。
场景2:线下子系统(仅包含模块A+B)测试时,需要做如下几步:
1)线上录制,此步只需要接入时一次性接入,后续无需关注
2)从数据管理平台中找到子系统A、B的压力数据和依赖数据,即筛选A、B模块的所有入口数据数据和出口数据,这些数据上都把了A、B的标签,可以很方便的从平台上获取到并灌入到回放集群中。
3)把回放组件以插件形式放入到被测试模块A、B中,开始回放模式,启动模块A、B
4)启动驱动工具,并把A的入口数据作为驱动工具的数据输入,开始测试
5)对测试结果进行分析、对比形成测试报告。
图6
通过上面的介绍可以看到,测试关心的子系统(比如A+B)时,只需要部署A+B两个模块,其他依赖的数据、服务都会通过录制的依赖数据来进行回放解耦,录制回放组件保证了数据的唯一性和一致性。
新模块接入过程可以分为如下几步:
1)把日志组件放到模块的工作目录下,开启录制模式,配置启动命令,配置要注入的aop规则
2)线下测试通过后可随着模块上线。
整体的工具具备如下特点:
1、通用性:
Java系统通用
回放数据可自定义定制
2、易用性:
模块一次性接入,无需修改代码
线上实时录制,无维护代价
3、仿真性:
线上抽样录制,仿真性高
可实现数据准实时更新,延迟小于2h,针对于接口变更频繁的服务更适合。
☞应用案例☜
目前本文介绍的基于AOP的测试解耦方案已经在DIFF测试和性能测试等方面在使用,下面选择了一个系统的DIFF测试作为例子来说明工作过程和整体测试过程,整体过程可以分为如下5步完成。
(1) 工具接入【一次性】
把组件包放到模块的lib下,通过agent参数进行启动,确认录制逻辑和模块功能是否有异常,若无异常便完成录制接入;若有异常则可能存在新的AOP类型需要适配,整个过程依托于线下测试环境。
(2) 线上录制
把组件放到线上模块中,建议和运维平台结合进行部署维护,降低维护代价,开启录制开关,便可进行持续抽样录制,录制数据通过大数据平台进行存储,整个过程依托于线上服务。
(3) 流量筛选
线上录制的数据按照一定维度汇总放到流量管理平台中,使用者可以通过平台筛选满足要求的流量,也可以给平台配置规则,自动化生成流量,同时把回放数据放入到回放集群中,整个过程依托于数据管理平台。
(4) 线下回放测试
通过(1)的方式把工具放入到被测模块中,启动回放模式,选择入口数据进行测试驱动,回放数据进行测试解耦,整个过程依托于统一的测试服务平台。
(5) 测试报告生成&分析
通过测试工具生成对应的diff报告,针对报告中的diff,可以通过分类的报告和流量分析能力辅助排查确定原因。
常见的DIFF方案可以分为:A:和线上结果DIFFB:不同版本进行DIFF 两种方案目前的测试工具都可以较好的支持,可以根据需要进行选择。
如下为DIFF测试框架图,其中被测子系统(A、B、C、D)中的部分模块(C、D)需要进行外部解耦,通过把回放组件注入,通过线上录制并存储于回放集群中数据来完成。
图7
为了能够让测试在不同的测试阶段发挥其应有的价值,在基于git的分支开发,主干集成,分支发布的开发模式下,设计了如图8的产品化CI流程:
图8
这么设计的初衷如下,业务线的同学可以根据自己业务线的需要来设计。
(1) 问题发现前置:在开发分支、主干和发布分支阶段分别添加对应的自动化测试任务,问题最早在开发分支本地代码阶段即可发现。
(2) 兼顾测试稳定性:触发的频度、触发的拓扑大小,可以根据业务线需要来设计。
(3) 多层测试保证质量:采用不同的拓扑大小和版本,开发分支阶段采用单模块的开发分支版本,主干采用子系统的主干版本,发布分支采用全系统的发布版本(非发布模块采用线上版本)
☞收益☜
作为基础服务能力已经在DIFF测试、性能测试、压力测试、故障测试等系统级测试中进行了支持,测试落地于5个复杂业务系统中(多个广告投放系统),线上流量接口覆盖达到90%以上,累计发现接近200个高优功能、性能和稳定性问题,为了降低触发代价,已经通过持续集成平台(jenkins,Agile等)持续进行自动化运行触发,保持了较高的任务调起量和执行效率。
☞后续规划☜
主要从基础能力稳定性和新能力拓展两个方面进行规划:
1)通用性建设:切面建设丰富,建设更多种统一分类的插件,提升更多的基础服务能力。
2)稳定性提升:针对不同数据格式的序列化/反序列化支持,降低序列化兼容性问题发生频率。
3)效率提升:数据管理、个性化处理和定制进行进一步提升,进一步降低使用者进行个性化定制的耗时,且能给出一些满足测试目的的定制建议。
杨方方
杨方方,哈尔滨工业大学计算机科学与技术硕士,现为百度商业服务质量部资深测试开发工程师,负责百度商业平台部相关产品的测试工作。
以上是关于藏经阁一种基于AOP的系统级测试解耦方案的主要内容,如果未能解决你的问题,请参考以下文章