方便的回归测试——diffy平台

  • 2019 年 12 月 10 日
  • 笔记

背景

前段时间,公司运维又双叒叕在迁移机房,带来的又是大量的回归测试,虽然负责的项目case还算健全,但是被迁移机房仍然存在大量的历史接口,有些甚至不知道是什么业务在用,但仍然在有少量请求,既然还在为少量用户提供服务,那就不能断然下线,但是这种服务该怎么回归呢?

解决方案

这种情况最简单的方案就是copy线上流量,通过工具diff结果来回归;之前配合部门的开发做了一个结果diff工具,但是功能简陋,无界面,操作十分复杂,结果diff全靠手动,用了几次实在忍不了;加上之前忘记在哪个公众号看到过diffy平台,所以决定试一下;

diffy介绍

diffy平台是Twitter开源的一个工具,通过配置可进行快速的结果对比,而且自带噪声过滤功能;工具原理参见下图:

  1. diffy本身是一个代理服务(proxy),自己构造的http请求,打到proxy;
  2. proxy把请求分发到三个地方:被测服务(candidate)、一号生产环境(primary)、二号生产环境(secondary);
  3. 被测服务与一号生产环境的返回结果进行diff,生成 全集diff结果(raw differences);
  4. 一号生产环境与二号生产环境的返回结果进行diff,生成噪声diff结果(non-deterministic noise);
  5. 通过去噪声,得到最终的 diff结果(filtered differences);
  6. 最终结果会在平台提供的html页面中展示;

如何部署

源码地址

关于部署,google百度之后发现没有一个可以说的明明白白的,希望本文能描述清楚;github上有两个版本

  1. twitter/diffy:https://github.com/twitter/diffy
  2. opendiffy/diffy:https://github.com/opendiffy/diffytwitter/diffy猜测是有内部依赖,所以无法编译成功;所以使用opendiffy/diffy进行编译;
编译方法

由于搜到的使用方法里能看到启动用的是个jar包,所以一直以为是java开发的,但实际上diffy平台使用的是scala语言,运行环境是java虚拟机,所以需要安装jdk,这里建议安装java8;编译命令:

  • ./sbt assembly(这个过程十分漫长,有条件的同学建议挂个代理)

编译好之后:diffy/target/scala-2.12/diffy-server.jar(diffy根目录的相对路径下)

启动

java -jar ./target/scala-2.12/diffy-server.jar          -candidate='127.0.0.1:80'          -master.primary='127.0.0.1:81'          -master.secondary='127.0.0.1:82'          -service.protocol='http'          -serviceName='ExampleService'          -summary.delay='3' #重试的延迟时间          -summary.email='[email protected]'  #邮件地址必填参数,但是貌似没啥用          -proxy.port=:8880  #http服务端口,结果查看页面          -admin.port=:8881  #查看请求状况http://localhost:8881/admin          -http.port=:8888 #proxy端口          -allowHttpSideEffects=true #无此参数只支持get请求          -excludeHttpHeadersComparison=false #是否排除header的差异,不同服务器,cookie,nginx版本可能有所差异,设置为true可以忽略这些差异

请求

测试case可使用大量线上流量(通过goreplay等工具)进行回放;或已有的接口测试用例;或构造大量随机用例;优点是不用关注结果正确性;

结果页面

注意事项

  1. master.primary和master.secondary 如果直接使用线上环境要确认是否有数据库增、改、写的操作,有类似操作的接口不建议直接使用线上环境,会造成线上数据库被灌入脏数据;
  2. 由于diffy平台目标是diffy结果,所以构造流量最好慢一点打到proxy接口,实测30qps以下功能基本稳定,大于30会有卡住的情况;
  3. 页面里看不到真实uri,如下图:

作者对此问题的解释是:大部分请求都包含请求参数,如果将所有参数展现到页面会大大降低用户体验,所以建议用户自定义uri