摘要
滴滴网约车致力于让出行更美好,平台为司乘提供良好体验的同时承载了广大群众的出行服务,致使我们对服务可用性的要求较高。更快地发现系统bug,可以让更少的司乘用户受影响。发现bug的能力更精细,可以让一些不易被用户感知但实际影响用户产品使用的bug更容易被发现。网约车服务端承接了网约车核心交易流程整体链路串联工作,其涵盖交易场景达百万级别,核心交易链路涉及几百个下游服务调用,这对我们的质量保障工作有了更高的挑战。本文提出了测试流量触发与测试结果分离的思想,并基于该思想做了两次实践,分别是在线上以更快召回代码bug为目标的线上流量巡检,在线下以提高测试效率为目标的测试流量验收。
背景及挑战
网约车服务端承接了网约车核心交易流程整体链路串联工作,其涵盖交易细粒度的场景达百万级别,核心交易链路涉及几百个下游服务。这督促我们的质量保障手段要粗细结合,既能保障核心业务的服务可用性,又要保障海量用户场景的正确运行。对于质量保障,在线上阶段,我们的主要挑战在于业务场景的量级太大,相关业务监控很难做精细化配置。在线下阶段,我们的主要挑战在于任意修改都可能带来几十个品类上千个场景的新功能测试工作量,一旦有场景遗漏,就会增加bug遗漏到线上的概率,从而引发影响面较大的系统故障发生。为此,网约车服务端利用测试流量触发与测试结果验证分离思想,在线上建立场景级流量监控手段,在线下利用多工具归一化验收方式,充分发挥多种工具的流量覆盖能力,大大降低手工测试比例。
在这样的业务质量保障过程中,我们发现业界通用的一些保障手段如自动化、流量回放、业务监控等在高复杂业务逻辑的校验能力上,心有余而力不足。
-
自动化:自动化作为最常规的手段,在网约车服务端的质量保障中起着不可或缺的作用,它能够对核心场景较大影响面的故障有提前拦截的效果。但其不足是精细化场景及校验点的覆盖需要付出非常大的成本,这里精细化的校验点指的是网约车交易主链路的接口测试中经常遇到的大量上下游交互逻辑的确认。
-
流量回放:流量回放作为低成本高覆盖场景的一种保障手段,也经常被应用到服务端的质量保障工作中。但是其往往依赖线下环境及其他依赖,如账号等,具有足够高的仿真度。同时其发现故障的过程往往伴随着处理大量无效的diff噪音,而很难快速确定业务系统“出了什么问题”。
-
业务监控:业务监控是线上阶段最常见的故障感知方式,往往能够达到较好的覆盖度和较快的感知及跟进。但是其定位一般设定为影响面较大的核心指标及通用指标,且一般对系统表现超过固定阈值或阈值范围来报警,每个报警指标的建立依赖业务系统技术改造来支持数据采集。这种方式决定了其不能高灵活度及时性的配置监控指标,对表现没有特定规律的小场景也无法稳定监控。
基于以上分析,网约车服务端期望有一种故障感知手段,能够以较低成本覆盖高复杂的校验逻辑且确定性高,从而进一步降低线上故障影响面。
在网约车一些业务的质量保障工作中,我们采用了测试流量触发与测试结果验证分离的思想,将测试流量触发的工作交给具有业务改动的服务方自己负责,其他方只作内部测试结果的验证。我们将改动方测试人员的测试流量进行录制并应用相应的业务规则,来对双方服务交互结果进行验证,将报错信息(流量匹配失败信息、规则引擎校验失败信息)透传给改动方测试人员,协助其验证改动方服务端与其他服务端的交互逻辑。由此可实现改动方测试人员的闭环测试和结果验证。
在此过程中,我们具备了以下2个成功经验:
-
测试流量触发与测试结果验证分离后,我们可以将测试流量触发交给改动方研发/测试,只专注解决测试结果验证,从而解决一些业务在团队内不闭环的问题。
-
我们实践了一套方法用规则校验来替代人工方式的测试验证。
测试流量触发与测试结果验证分离思想
测试流量触发与测试结果验证并不是什么新技术,在我们传统的质量保障手段例如自动化和流量回放中,我们可以把它切分为测试流量触发与测试结果验证两个步骤。具体如下图所示:
在构造请求方面,自动化是通过人工构造,而流量回放是通过录制线上用户触发的流量。在测试结果验证方面,自动化是通过编写assert校验来实现,而流量回放是通过diff来实现。
当我们将测试流量触发与测试结果验证分离后,我们可以集中火力,根据需要对两个维度单独发力。
-
在测试流量触发维度,我们可以只关注工具对业务场景的覆盖度,并以提高覆盖度为目标,对不同测试手段进行组合使用。这里的测试手段可以不局限于工具化的测试手段,实践过程告诉我们,对于迭代的新功能,我们总是有一定比例的流量触发是靠人工的方式去完成的。这里我们主要把控两个核心点:测试流量对业务场景的覆盖度、测试场景触发的重复度及成本。对于前者,当我们的测试场景总集有了之后,很容易能够度量出来。对于后者,我们关注的是以达到一定质量要求为目标,需要进行的测试轮次和每个测试轮次的流量触发方式及触发成本。这里我们将RD/QA的测试统一来看,通常认为用最低成本的测试手段去完成更多轮次的测试,是一种在效率维度很好的方式。
-
在测试结果验证维度,我们只关注工具对业务校验点的覆盖度,并以可接受的覆盖度为条件来确定该种方式的应用边界范围。这里的业务校验点是为验证迭代的代码提供的服务符合业务场景。验证范围包括接口入参、出差、下游调用、配置读取、存储数据等。
在网约车服务端,基于测试流量触发与测试结果分离思想,我们做了两个实践,接下来详细介绍。
线上流量巡检——0测试触发全结果验证
线上流量巡检的目标
线上流量巡检是网约车服务端对测试流量触发与测试结果验证分离的一种实践,将该思想实践到生产环境中,我们可以达到下述目标:
-
几乎0成本完成较全面的流量触发(场景覆盖)的目标:我们将每一次真实用户对系统的请求都看做是一次对该系统的测试,而对真实用户流量进行结果验证,就完成了一次系统健康度的检查。规避了自动化等手段较高场景覆盖成本的弊端。
-
对服务的健康度检查覆盖的流量元素更加全面:除覆盖流量的出入参,还覆盖了接口调用链路中的上下游、存储、配置等,从而发现问题能力更强。
-
对生产环境无痕。
整体方案
常规手段如流量回放一般会认为线上系统的历史流量总是正确的,用这样的流量在线下再回放一遍来完成改造后系统的正确性验证。线上流量巡检总是致力于找到线上系统有问题的历史流量,这些有问题的流量是在线上系统有代码bug发生时产生的流量。从而更快地发现线上系统“生病了”。整体技术方案中,我们与流量回放共用了流量录制的能力,但在对流量的处置中,我们的路径及思路截然相反。
-
致力于找到流量池中表现不达预期的那部分流量。
-
将流量进行分桶(分桶条件由流量元素形成的规则组成),分桶的目标是找到每个流量的归属场景。
-
对分桶后的流量进行校验,校验的内容是该流量归属业务场景的逻辑验证。
线上流量巡检的整体架构如下图所示,核心处理流程有:流量录制、流量解析及处理、流量分桶及校验、异常报警。
接下来详细介绍实现方案,具体如下:
-
流量录制:流量录制的内容仅为我们关心的流量元素:接口的入参、出差、下游调用入参、出差、依赖配置的读写、依赖数据库的读写、公共日志的读写。滴滴自研的fastdev流量回放工具提供的流量录制能力满足了我们绝大部分的诉求,同时该工具已完成滴滴服务端绝大部分服务的覆盖。录制的内容呈现为字节流,需要进入数据预处理模块。
对线上用户单接口的流量元素录制后,将线上流量存储到ES前,从原始数据中提取出敏感信息,然后进行加密,使用加密后的数据对敏感信息进行局部替换,对原始数据中的敏感数据进行提取和加密,最终存储的是加密后的流量日志信息。
-
流量解析及处理:流量的预处理包含了字节流到完整应用层协议解析、异常数据过滤、流量关键元素的提取等步骤。目标是得到标准化的流量,可供后续规则引擎使用。
-
流量分桶及校验:流量分桶的方法及校验内容都是与业务相关的,由编写同学梳理业务逻辑之后,编写出场景匹配条件和场景的校验点。
-
a. 整体系统采用基于动态编译的语义规则设计,由用户给出语义化指令来定义接口流量的预期,一个运算单元主要负责根据指令集合匹配业务场景和校验业务预期,具体指令的计算利用动态编译方法调用相应的库函数处理。
-
b. 为提高处理速度,采用分布式计算,将计算任务进行数据划分,但对最终处理结果做统一结果规约。
-
c. 为避免重复计算,将处理结果进行哈希存储,在计算任务开始之前,会先对流量特征进行哈希查找有无相关处理结果,若有,直接使用缓存结果作为最终结果。
-
异常报警:当线上巡检的规则引擎在做结果校验时,发现不符合业务逻辑的流量,根据报警策略进行报警,报警信息包括关注人、流量报错信息、问题排查辅助信息等。
-
a. 报警策略考虑了业务应用场景,有几种可供用户自由选择:失败强校验、失败率达到阈值、异常流量告警。
-
b. 报警策略利于报警聚类来降低报警频次,同时可简单对报警归因。
这里核心关键点是通过流量自身的诸多元素组成规则来对流量进行分桶和规则校验,而非预先设定的某一宏观指标。
当前收益
网约车服务端在2020年初开始实践上述方法到质量保障工作中,2023年已覆盖服务端大部分服务,每年100+线上bug的及时召回,使其成为线上质量的有效抓手。
线上巡检因为其报警的精确度和灵敏度,可广泛应用到日常需求,作为需求变更灰度过程中的结果验证和问题及时发现的有效手段。
在服务调用方众多的平台类业务或者中台类业务的使用收益是更加可观的。
后续规划
当前线上巡检技术被证明适用于网约车服务端的质量保障模式,并且在需求变更灰度过程中能够灵敏度更高的反映生产环境状况。目前网约车服务端在进一步提高迭代需求的线上巡检覆盖度,并多次在变更灰度过程中发现代码bug,快速召回线上问题,及时止损。
测试验收——测试触发去重及归一化结果验证
测试验收的目标
测试验收是网约车服务端对测试流量触发与测试结果验证分离的另一种实践,该实践主要应用到线下环境,核心目标有:
-
测试工具化:以提高工具化流量触发比例和测试结果验证比例为目标,将手工测试的场景不断实现工具化覆盖。
-
测试流量触发去重:以归一化结果验证为手段,达到对不同测试方法、不同测试数据来源的结果进行验证,避免重复测试。
背景
网约车服务端因为其业务特性和服务特点,当前的测试方式是纯白盒测试。在测试过程中,QA需要完成以覆盖所有改动代码为目标的单系统服务端测试和以覆盖所有影响面的全链路服务端测试。如此,我们面临以下挑战:
-
我们一个典型需求在不同角色如RD、QA、PM之间存在较多的重复测试,在不同服务QA(服务端QA、客户端QA、算法策略QA)之间也存在较多的重复测试。
-
在业界这类问题往往是利用自动化/工具手段去完成整个测试过程来将重复的测试提高效率。在滴滴服务端,我们所面临单一工具局限性导致使用单一工具覆盖所有测试场景及校验点的成本极高。
在一些单方面修改业务测试验收模式中,我们实践了利用工具化验证替代人工验证的可行性。在闭环的内部业务中,我们可以使用工具触发流量来替代手工触发流量,提高流量触发侧的效率。
整体方案及应用实践
解决上述问题的核心关键点是找到一个能够覆盖绝大多数测试验证场景的手段,而线上巡检技术解决了我们这一问题。我们可以将网约车服务端测试的绝大多数的验证场景转换为线上巡检的流量匹配规则+校验规则。不同于线上巡检的是,在线下环境,测试流量触发需要被考虑。同时技术方案的一致性让我们能够将线下为提高测试效率编写的验收规则,直接在线上运行变成生产环境服务健康度检查的线上流量巡检规则。
当我们把线上流量巡检规则应用到线下测试流量时,我们完成了对测试结果验证,此时我们需要做的就是让测试流量的触发阶段用最低成本的工具去覆盖。其中对于新需求迭代,我们将测试场景分为回归场景+新功能测试场景。对于回归场景,我们的流量触发能力大部分是具备工具化能力的。对于新功能测试场景,此种模式在演进过程中存在以下3种阶段:
-
较多占比的手工触发测试场景:此时我们的主要收益为对测试结果的验证,可应用场景如:提测需求的新功能准入测试、RD自测需求。
-
不断提高工具化触发测试场景占比:此阶段我们不断寻找无法被工具化触发的场景,通过改进工具能力或者其他方式,不断降低手工触发的测试场景占比。
-
较高或者完全的工具化比例触发:此阶段的QA,主要工作在于根据需求和技术方案,做测试用例设计,并根据用例实现工具化触发手段及验证规则的编写,整个测试过程是工具触发及验证后,给出测试报告,提交bug移交给研发,重复以上步骤直到完成测试交付。
同时线下测试验收编写的规则在需求上线过程中转变为线上流量巡检的规则,在需求上线/放量阶段对线上服务做健康度的检测,按照这个思路,一个典型的需求交付过程如下图所示。
当前收益
在测试验收落地过程中,我们主要关注的过程指标是工具化场景覆盖度和结果指标测试效率的提升率。
-
网约车服务端通过在业务试点,初步拿到在适用项目中总体测试提效40%左右的收益。
-
实践发现测试场景链路较长的业务、测试轮测较多的需求中,测试提效收益更加明显。
总结及展望
在网约车服务端测试和质量保障方法的探索中,因为业务模式和系统架构导致系统存在很多非常“胖”的服务,从而导致测试复杂度很高。当服务耦合度高且调用链路庞大的情况下,业务对数据构造、环境稳定性、工具的验证能力要求都非常高。依赖单一传统能力想要解决所有问题,在以往的探索中,我们付出了极高的人力成本代价。我们也在不断在问自己一个问题,为什么我们的测试这么难,投入这么高?为什么一定要做白盒测试?在不断向内分析和向外借鉴的过程中,对出行服务的业务特点和合适的质量保障手段渐渐清晰。当前我们的探索还在持续,也没有非常彻底地解决掉服务端测试的所有问题,但,我们一直在路上,永不停歇~
关注滴滴技术公众号,获取更多技术干货