阿里 qa 导读:我们经常使用线上质量来衡量质量保障的有效性,这就包括了三部分:可见的(已经发生的故障、冒烟、客诉等) + 雷区(随时可能发生问题,例如特殊场景、异常场景等)+ “无人区”(例如代码有bug,但是不会有流量走到),本周小编推荐的文章就是尝试通过线上场景提升质量保障过程的场景覆盖率。
背景
广告界有一句名言,说的是商业公司在营销中投入的无奈:
我知道有一半广告费浪费了,但我不知道是哪一半?
--百货业之父约翰·沃纳梅克(John Wanamaker)
有趣的是,这个句式只要稍加改动,就可以用来说明我们在质量保障中的各种无奈:
我知道有一半的场景没有覆盖,但我不知道是哪一半?
我知道有一半的用例是无效的,但我不知道是哪一半?
...
需要说明一下,这里的“一半”并非准确的数据,是一种心理的感觉,是一种机会成本的体现。
之所以遇到以上的难题,主要原因是:保障手段的效果难以衡量,恰如商业公司在广告投入上的效果难以衡量。要衡量某个物体,首先我们需要有一个标尺(某名人说过 )。质量保障有效性的标尺,归根到底就是线上质量,包括了三部分:可见的(已经发生的故障、冒烟、客诉等) + 雷区(随时可能发生问题,例如特殊场景、异常场景等)+ “无人区”(例如代码有bug,但是不会有流量走到)。
根据奥卡姆剃刀原则,质量保障不需要考虑上图“无人区”部分,只要考虑当前存在的线上场景。这也是万象平台的立足点。
小结为一句话,万象计划通过线上场景来解决“另一半”的问题。说人话:提升质量保障过程的场景覆盖率。
背景了然,准备发车~
第一站,解决什么?
根据前面的分析,我们知道,万象是通过线上场景来提升质量保障的有效性。这里的质量保障太宽泛,需要做进一步的细化,我们不妨一起来看看除了测试以外,在整个研发流程中,还有哪些质量保障相关的环节。
图中包括了:新功能测试、回归、性能测试、灰度、攻防演练五个部分。通过分析可以看出,其中新功能测试、灰度都只跟“未来”的线上场景有关,即只有在代码发布后才会有真实的流量进来。剩下的三个部分回归、性能测试、攻防演练都跟当前的线上场景密不可分。
由此,我们要解决的问题就是:如何通过线上场景,来提升回归、压测、攻防的有效性?
--> 探讨(本文中会针对部分内容进行深入的探讨,属于“分支”,跳过不影响“主线”,大家可以自行选择是否阅读。)
-->探讨:关于回归的范畴
单个系统的技改,对于该系统测试来说是测新,对于场景测试来说,是回归;多个系统间的链路改造,对于局部联调来说是测新,对于端到端场景测试来说是回归。因此,回归的范畴是变化的,端到端场景回归,可以涵盖最大范围系统技改、多系统链路改造。测新需要分析、造数、建用例、写校验,而回归则基本是0成本,所以端到端的场景回归站在技改项目中往往能体现出巨大的优势。
第二站,如何解决?
面对一个复杂的问题,首先要做的就是把它拆解成多个子问题,然后逐一攻克,原问题的解即子问题的解的合并(某名人2号说过)。我们这里可以采用最简单的数学等式来拆分上面的待解问题,具体如下:
端到端回归
用例 = 数据 + 执行 + 校验 + 度量
简单来说,执行一次测试,核心步骤就三步:
- 构造一个特定的请求
- 向一个特定的接口发起请求
- 获取结果并校验
“构造一个特定的请求”,其实不仅仅是一个简单的请求体,还包括了每个参数所代表的基础数据。以外卖下单为例,请求体包含了几十个必要的参数:用户 id=u1234,商户id = m1234,商品id = i1234 等。其中,用户u1234代表的是一个真实的用户,在用户系统及其它相关系统中保存了实体数据,例如:用户的基本信息、用户的地址信息、用户的权益、用户的标签(新客、老客)等等。所以,上面等式中的“数据”不仅包含了请求体,还包含了所有必要的基础数据--在本文中将其定义为静态数据,方便于动态数据--请求体、mock数据等做好区分。区分的原因,在万象架构一节会详细介绍。
在批量进行自动化回归的场景中,为了形成测试有效性不断提升的飞轮,往往需要加入“度量”这一步骤,用来衡量本次回归的效果以及没有用例的有效性,并以此来进行用例的汰换。
--> 探讨:场景和数据的关系
场景通常可以分为两种,单一场景,例如:一个商户在饿了么上架一个商品;复杂场景,例如:一个用户甲在饿了么下单购买了一个外卖,完成支付后,商家乙接单了,制作完毕后呼叫了物流,最终骑手丙将外卖送达,并完结了订单。我们可以简单定义场景:
- 单一的场景:用特定的数据,调用特定的接口;
- 复杂的场景:按一定的顺序,用一系列特定的数据调用一系列特定的接口。
通常我们要解决的是单一场景,因为复杂场景可以拆解为多个单一场景。根据上面的定义,我们就把场景映射为了“数据”,关于数据的进一步分析,会在下一节万象的架构设计中展开。
全链路压测
压测 = 数据 + 流量模型 + 执行 + 校验 + 度量
压测的效果,取决于流量模型的真实性。以外卖下单为例,一个名下有100张营销券的用户下单,和一个名下无券的用户下单,两者所消耗的营销域链路资源(主要是计算资源)差别是巨大的,在压测流量中,前者和后者的占比,将极大的影响压测结果。因此压测的流量模型要尽可能的还原线上各种真实数据的占比,而这个的前提,就是要在影子链路尽可能复刻线上各种真实数据。
攻防演练
演练 = 数据 + 执行 + 攻击 + 防御体系
结论
至此,问题拆解完毕,通过上述的三个等式,可以看到等式右侧拆解成出来的公共项有:数据、执行、校验、度量。有了这4个子项,接下来就是“分而治之”。与此对应的,万象平台所解决的就是数据准备、执行、校验、结果度量几个难题,简单归结一下万象的解题思路:
数据:来源线上真实场景,构造影子数据;
执行:对接现有的各种执行平台,不重复建设;
校验:模型比对、接口结果比对,支持双工比对;
度量:通过特征分析,客观度量整体场景覆盖率、单个用例的有效性。
小结一下
万象目前重点保障:场景回归、全链路压测、攻防演练;
万象聚焦解决:数据、执行、校验、度量4个难题。
第三站,万象的架构
正所谓,没有明确目的的架构设计都是“墙上芦苇”。通过前面的探讨,我们已经明确了万象的目的、目标,以及要解决的核心问题。
目的:提升质量保障过程的场景覆盖率。
目标:
- 提供通用的场景量化方案;
- 提供通用的场景构造方案;
- 提供通用的执行、校验方案;
- 1次接入,0成本运维。
核心能力:
- 数据引擎
- 执行引擎
- 效果度量
万象平台分为两层,应用层和核心层。应用层负责业务接入、配置管理和结果呈现,目前暂未开放前端,各个功能直接通过后台提供。核心层是万象平台的主要功能区,包含了三部分:数据引擎、执行引擎和效果度量,分别对应到上一节提到的几个通用能力。
数据引擎
数据引擎最核心的功能是:数据降维、场景复刻。依旧以外卖交易为例,天级的数据量是千万,月级的数据量是亿,因此需要先将数据量降低4个数量级,才有可能在影子链路构建全链路场景。
数据降维
这是一个归类问题,就是把亿级的订单归类为万级的场景。归类的方式有很多,例如代码覆盖率、基于流量出入参及自调用返回分析等。万象采用的是DB字段统计归类的方法,思想的基础是业务的重要字段很大可能会持久化,基于这些字段的组合就能还原重要的业务场景。我们把DB字段的不同组合成为一个特征(对应一个场景),例如:平台新客 + 购买了外卖 + 享受了店铺减 + 配送优惠。
在了解了上面归类方法后,滑动窗口和黑白名单就非常容易理解了。DB中的字段随着业务的不断迭代,会展现出一种趋势,因此上述的统计归类也需要随趋势变化,实现手段上就是:每天统计从30天(可配置)前到当前的数据,并更新特征库。DB中不是所有字段都有统计价值,可以通过“黑白名单”进行调整。
场景复刻
场景复刻,简单来说就是在影子链路复制出一个线上场景,包括了静态数据复制(基础数据)、动态数据复制。
静态数据复制实现方案,是在数据降维过程中产生了特征(即场景),同时记录下该特征下的线上真实案例,例如:特征1(平台新客 + 购买了外卖 + 享受了店铺减),案例(真实订单1),然后根据真实订单1,在影子链路创建影子用户、影子商户、影子店铺、影子优惠、影子用户资产等。
动态数据复制,主要包括请求构造、mock构造(可选)。针对简单的请求体,可以通过定制化的工具类来生成,例如:外卖场景中的商家接单只包含一个参数;针对复杂的请求体,往往需要通过采集日志的方式,获取线上真实请求日志进行处理。
-->探讨:静态数据复制的“时差”
万象在复制场景的时候,真实的场景已经发生了,也就是说这是一个后置的过程。后置会带来一系列的难题,其中最复杂的是静态数据的回溯。我们来看一下外卖中常见的一个案例:新注册的用户约翰,购买了一份外卖,使用了一个平台直发的5元红包,同时也享受了平台新客优惠。最终交易完成,约翰愉快的享受到了美食,并在系统中留下了一笔交易订单。我们拿到这个交易订单,进行静态数据复制时,会发现,当前的约翰已经不是新客 -- 与交易达成前的“新注册的用户约翰”已经不同了;同理,当前的约翰名下已经没有5元红包,也与之前不同了。因此,需要分析当前交易的情况,做数据还原,即数据回溯。
执行引擎
执行引擎划分为执行和校验两部分。执行又可以拆解为控制模块和运行模块,控制模块相对简单,主要包括调度管理、流程编排、执行模式配置(即,运行环境、是否双工运行等);运行模块相对复杂,包含了跟各个平台的打通,因为每个平台的接入方式都不一样,所以要逐个做定制。
以对接天算为例,需要把圈选好的万象场景数据以用例集的方式同步到天算,确保用例数据都同步成功后,保存天算返回的用例列表id,每次执行带上id直接调用天算执行接口,之后万象监听每一个用例的执行结果并保存,以便后续进行校验。
校验部分,支持基于查询接口返回结果的模型比对、支持指定接口的response 比对。以外卖交易为例,执行通常选择双工模式(即,相同的请求分别在生产环境和待测预发环境执行),万象监听到生产环境返回的订单号1,和待测预发环境返回的订单号2,然后分别调用订单查询接口,比较两者的模型是否一致,默认是所有字段比对,支持配置黑名单;万象也会根据配置,从SLS获取指定系统的、指定接口的response,并做字段比对。
-->探讨:实时mock适用的场合
实时mock,就是应用系统在识别到万象流量后,调用某个指定下游服务的时候,定向到访问万象统一mock服务,万象会识别场景数据,返回该场景的真实案例的结果(即采集的线上真实数据)。不难看出,该功能需要在应用系统中做改造,有一定的成本。
采用实时mock,实属情非得已,在两种情况下会用到,第一种是影子链路走到一半走不通了,例如外卖场景下交易在弹内,物流在弹外,而弹内外的影子链路没有打通;第二种是某个服务的结果是随机的,例如外卖的百亿补贴,同一个用户、连续两次访问可能得到不同的结果。
效果度量
效果度量最常用的一个场景是,万象执行结果覆盖了线上真实场景的占比。有了数据引擎一节提到的特征分析能力后,效果度量相对简单。万象用例执行完毕后,产出执行结果表,通过特征分析,得到结果特征数据,然后跟线上全量场景特征数据,两者的商就是覆盖率。
此外,度量还有一个比较重要的场景是,计算一个特定万象用例的执行结果的有效性,简单来说就是这个用例执行后的特征数据覆盖的线上真实场景的流量占比。前面的句子比较难以理解,举个简化的例子,假设线上真实场场景--用户点外卖享受了店铺优惠3元,流量占比为3%,万象复刻了这个场景,并将该场景圈选到了回归库中生成了回归用例1。回归用例1在影子链路执行就是场景“用户点外卖享受了店铺优惠3元”,假设店铺配置的优惠有效期是1周,那么,1周之后,该店铺已经没有优惠,回归用例1再次执行就变成了“用户点外卖,没有享受店铺优惠”,导致预期的场景没有被覆盖到,用例失效。
小结一下
万象平台核心模块有:数据引擎、执行引擎、效果度量;
万象数据引擎的核心功能是:数据降维和场景复刻;
万象执行引擎的核心功能是:是对接各个自动化平台、提供实时mock能力。
俗话说的好,theory is empty, show me the case!
第四站,使用情况
目前在万象落地比较成熟的是:2 + 1组合,2个回归库,1个攻防演练。1.外卖交易下单回归,典型的C端场景,特点是场景多、基础数据复杂,是接入、运维的天花板;2.营销活动回归库,典型的B端场景,基础数据单一,接入和运维的成本低;3.强弱依赖演练,提供定制化的万象流量。本节就以外卖下单回归库做一个简单的展开。
外卖交易下单回归库
累积用例:10000+个
业务覆盖度:85%(流量占比)
执行情况:发布前自动运行。
业务场景覆盖率统计情况图:
场景的概率分布长尾图:
上图是线上某一天的场景单量分布图,纵轴是单量;横坐标是一种特征组合(即一种场景),用唯一的特征id标识。可以看出是一个长尾图,横轴坐标(不同的特征组合数量)在10万量级。
上图是万象回归库运行后的结果,第一列是排名(订单量从大到小),第二列是特征id,第三列表示是否被覆盖,可以看到top63的场景都覆盖了,top100的场景只有靠后的个别没有覆盖到。
第五站,未来规划
万象目前的接入成本还比较高,后续会持续的推进产品化进程,方便更多的业务线接入。另外,后置数据分析、压测流量模型建设等方面,还有很多待深入挖掘的地方。
如果说Doom是以流量为核心的回归体系,那么万象就是以“场景”为核心的质量保障体系。在“场景”这个主干上,能做的远远不止于回归、全链路压测,期待一起探讨更多的可能性!