阿里创新自动化测试工具平台--Doom
摘要: 阿里内部诞生一了个依赖真实流量用于自动回归的自动化测试平台,通过创新的自动mock机制不仅支持读接口的回归验证,同时支持了写接口验证,在内部产生了极大价值,有价值的东西就应该分享,目前该工具已经作为云服务对外开放。
背景
信息系统上线后通常会需要迭代升级甚至重构,如何保证被修改后系统原有业务的正确性非常重要。不复杂的业务系统通过一些常规的自动化测试工具加上人工测试可以解决,但对于业务十分复杂的系统,回归测试将变成一项浩大的工程。
一个实际的例子:阿里巴巴作为一家以电商为核心的集团公司,交易系统和稳定性的重要性不言而喻。整个交易系统在多年的发展过程中,经历了很多业务的上下线,维护的人员也换了一波又一波,几乎没有人能梳理清楚其中的业务和代码。当它不得不面临一次全面升级的时候,其回归测试的困难度难以想象。因为常规的自动化测试工具需要准备测试数据、编写脚本,因此覆盖率不高,因此无法满足需求重构后的回归验证要求。
doom平台的出现解决了这一难题,它通过复制线上真实流量去做自动化回归,通过它发现了很多重构带来的bug,同时加快交易重构项目的上线进程。同时通过录制流量作为用例来实现日常自动化回归取代传统编写脚本的自动化回归大大提升了回归效率和覆盖率。
因为其解决方案的通用性,我们把这它拿出来给大家分享,同时也开放了云服务希望能支持到有需要的用户。
平台介绍
什么是doom平台
doom自动回归平台是一个将一部分线上真实流量复制并用于自动回归测试的平台。 通过创新的自动mock机制不仅支持读接口的回归验证,同时支持了写接口(例如用户下单接口、付款接口)的验证。它最底层借助了java的instrument实现aop因此,目前仅支持java应用的接入使用。其原理图如下:
它与tcpcopy或者diffy的区别:tcpcopy、diffy是在应用外的网络层实现流量录制和回放的,它们只能实现一些只读页面的验证。doom是在应用内部通过aop切面编程方式实现的流量录制和回放功能,因此可以做到应用内部接口级别的回归验证,当然也支持服务级别或者http级别的回归验证。通过独创的中间件级mock以及内部自定义的mock,可实现写流量的回归验证以及跨环境的回归验证(线上引流到测试环境)。
应用场景
系统重构时,复制真实线上环境流量到被测试环境进行回归,相当于在不影响业务的情况下提前上线检测系统潜在的问题。
可以将录制的流量作为用例管理起来进行日常自动化归回。
优势
低成本:无需编写测试用例,通过流量录制形成丰富的测试用例。
高覆盖:一方面线上大量真实流量确保覆盖率,另一方面支持中间过程的验证,例如发送消息的内容、中间计算过程等等的全对象的对比验证,传统手工编写验证点很难实现。
支持写流量验证:(注:写流量是指可能导致有数据变更的流量)不用担心写流量回放污染应用数据,支持线上引流到测试环境以及写流量的自动化mock。
低应用侵入:通过隔离容器技术、字节码级别的AOP技术、中间件级MOCK避免接入类冲突以及降低接入成本。
如何使用
doom平台在阿里巴巴内部,特别是一些核心系统得到广泛使用,因此我们决定把这个产品开放出来,以云服务的形式免费提供给大家使用。doom支持 云效 上的应用直接申请使用,也支持任意能访问公网的应用直接申请使用。
平台文档:接入使用指南
平台链接:doom平台
原理
如何实现回归验证?
对于web应用来说,请求最终都通过发起http请求方式来完成。我们假定生产环境应用会正常的响应用户的请求,通过aop的方式将请求入参及返回结果以及执行过程中的一些快照数据例如访问数据库的入参和返回结果、访问远程服务器的入参及结果保存下来。然后将快照数据发送给测试机器(代码发生变化的机器)完成一次回放过程。通将落库数据、调用后台请求的数据以及返回结果和线上真实请求发生时的数据进行全量对比,发现其中的差异,从而识别被测试系统的问题。针对后台应用来说也是如此,只是后台应用一般都是通过rpc请求实现,这时只要记录rpc入参、rpc返回值以及中间快照数据用于回放即可。
如何保证数据库不被污染?
mock是单元测试常用手段,用来解决接口未完成或者调不通的情况。将这个特性进行延展,在线上执行真实请求时就把写数据库的请求以及对外服务的访问保存下来,在回放时当执行数据库或者调用后台的服务进行mock,这样回放时不会真正的访问数据库,也不会真正的发起对后台服务的调用,因此会影响业务数据,甚至可以在线下环境进行回放,因为mock数据来源于真实请求,也省去了造数据的麻烦。
如何实现对外系统请求的mock?
应用会通过各种各样的中间件对外发起rpc请求,可以通过平台配置的中间件隔离来设置,平台客户端会对这些中间件进行aop处理实现自动的mock,不需要人工去配置具体的rpc接口。如果不支持的中间件请联系我们,我们会对其做适配开发。
如何解决回放时程序执行流程可能和线上真实流程不一致?
在生产环境程序执行时的一些内存数据状态和回放时测试服务器的内存数据状态往往会出现不一致,这些不一致会导致程序的执行流程不一样。例如本机缓存、内存开关、session查询等等。那么要如何解决呢?平台提供了自定义mock机制,将这些会导致不一致的代码片段进行mock。例如将缓存的get方法进行mock,那么如果线上读缓存时有数据,那么回放时直接可以用这些缓存数据进行mock即可,确保了回放的流程和线上真实执行时一致。
如何解决对比时的噪音?
回放时和录制时必然存在一些差异,例如服务器ip、时间、以及一些随机数等等。通过两种方式去解决:
排除法:平台支持指定字段排除对比,将不需要的字段排除即可。
指定对比法:将关心的业务数据进对比。
系统架构
部署图
如图上所示,云服务提供配置管理功能,而在用户机房可以通过扩展实现自定义数据存储或者直接使用阿里云oss存储产品来实现用例或者流量的存储。配置之所以集中管理是为了方便平台升级,而支持数据自定义存储则提供给了用户更多的存储选择。
图中A企业完全使用平台功能,如果平台功能不满足需求也可以像图中企业B一样,基于平台提供的录制、回放等等能力去实现自己的稳定性/回归测试平台。
客户端服务端架构
上图为客户端服务端的架构图。客户端为接入应用嵌入的一个功能模块,可以负责流量录制、流量回放、中间件mock、中间件隔离、流量对比分析等等功能。服务端提供客户端相关的配置信息,例如要录制哪些流量,录制比例是多少、哪些ip服务器需要被录制等等。客户端的一些状态信息也会发送给服务端方便展示管理。另外只有当发生对比异常时,服务端才会发送异常数据给服务端用于查看分析。
要实现不同企业的不同中间件mock,客户端需要扩展不同的中间件mock插件来实现。各个插件通过中间件插件管理器去管理,平台支持一些常用的中间件也支持扩展。除了mock外还需要提供了一个中间件隔离机制,例如通过在中间件最底层做一些隔离,避免在mock失败的情况下不会访问到数据库,保证回放时业务数据的安全性,当然如果是在非生产环境进行回放测试也可以避免这个风险。
平台开放
录制数据存储到哪里?
平台默认将录制数据保存到oss,也支持用户通过扩展实现使用自己的数据存储服务。
能基于doom平台实现自己的用例管理执行平台吗?
doom平台开放了流量的录制、回放以及对比的api,有需求的用户可以基于这些能力快速搭建一套属于自己自动化回归测试平台。