1、Diffy 是什么

  • Diffy 是 Twitter 的一个开源自动化测试工具,是一种 Diff 测试技术。Diffy 通过同时新代码和旧代码的实例,对比运行结果来发现服务中的潜在错误。
  • Diffy 充当代理并将它收到的任何请求多播到每个正在运行的实例

    2、Diffy 解决什么问题

    随着项目的迭代,产品功能不断增加,项目会变得越来越复杂;而从质量保障的角度,除了要保障好每次新增、优化的产品质量外,还需要确认新增或修改的功能不影响之前已存在的功能。若要进行产品功能全量回归,这个测试的工作量将会非常巨大。
    因此 Diffy 提供了较好的解决方案,它基于稳定版本和它副本的输出,对候选版本的输出进行严格对比,以检查候选版本是否正确,大大降低了回归工作量

    3、Diffy 工作原理

    Diffy 充当代理,它能够将来源请求分发到三个不同的服务实例中,通过对各个版本系统的输出进行对比,做出最终的结论。整个运行流程为:
    image.png
    Diffy 需要三个版本的实例,以实现它的噪声过滤和对比功能,它们分别是:
  1. 候选版本(candidate):该版本是待测版本,相对于生产环境版本有着更新的代码
  2. 稳定版本(primary):该版本通常是已经上线版本,或者是已知功能正常的版本
  3. 稳定版本副本(secondary):该版本是稳定版本的副本,和稳定版本运行相同的代码,主要用于排除噪声

如上图所示,Diffy 能够比较 primary (线上稳定版本) 和 secondary (线上稳定版本备份) 的差异值,通过对这些差异值做减法来确定接口的噪声(比如时间戳、随机 ID 等)
通过比较 candidate (测试版本) 和 primary(线上稳定版本) 得到基本的 diff 结果;最后通过比对基本的 diff 结果消除噪声后的结果,得到最终的 diff 结果

其中:

  • 原始区别:为候选版本 和 稳定版本之间输出的区别,其中可能会包含噪声
  • 噪声:从稳定版本 和 其副本中获得,如果两个运行相同代码的系统输入相同输出却不同,则 Diffy 会认为这是开发人员不需要关心的噪声(比如时间戳、随机 ID 等)
  • 基于上述两个区别集合,Diffy 可以识别出 候选版本 和 稳定版本 真实的区别,这些区别很有可能就是一个缺陷

    当然,对于一个概率性出现随机值,仅仅一次请求的结论可能是不准确的。 例如:
    对于一个 50% 概率出现 true 或者 false 的布尔值,则有 50% 的概率会出现候选版本和稳定版本的不同,同时又会有 50% 的概率出现稳定版本和其副本出现不同(即将这个值认定为噪声),最终会有 25% 的概率认为这是一个缺陷。因为此时稳定版本和其副本值相同,候选版本和稳定版本值不同。因此,Diffy 还会聚合原始区别和噪声,当发现二者出现的概率类似的时候,会认定之前识别出来的缺陷属于误报

4、Diffy 的安装与部署

4.1 拉取代码并构建

前面简单介绍了 Diffy 的作用和原理,了解了 Diffy 介绍 的作用和原理后,可以将 Diffy 工具的源码拉到服务器中:

  1. git clone https://github.com/twitter/diffy.git

代码拉取完成后,进入到 diffy 目录后,使用 ./sbt assembly 进行构建。但需要注意,windows下会构建失败
构建完成后,在 diffy/target/scala-xx/diffy-server.jar 下就能找到可执行 jar 包
其实构建的目的就是为了获取可执行的 jar 包,我这里已经有构建好的,可以直接下载并上传服务器即可直接使用:diffy-server.jar%E4%B8%8B%E8%BD%BD%E5%90%8E%E4%BF%AE%E6%94%B9%E4%B8%80%E4%B8%8B%E6%96%87%E4%BB%B6%E5%90%8D)

4.2 部署 diffy 服务

有 jar 包后,可以运行 jar 包并初始化一些diffy命令:

  1. java -jar diffy-server.jar
  2. -candidate=localhost:9992
  3. -master.primary=localhost:9990
  4. -master.secondary=localhost:9991
  5. -service.protocol=http
  6. -serviceName=My-Service
  7. -proxy.port=:8880
  8. -admin.port=:8881
  9. -http.port=:8888
  10. -rootUrl='localhost:8888'
  11. -summary.email=zxxx@xxx.com

相关参数介绍:

参数配置 含义
java -jar diffy-server.jar jar包路径进行运行
candidate=localhost:9992 待上线版本部署地址,即候选版本
master.primary=localhost:9990 已上线版本地址 1,即稳定版本
master.secondary=localhost:9991 已上线版本地址 2,即稳定版本副本
service.protocol=http http 协议或 https
serviceName=My-Service 服务名称
proxy.port=:8880 后台输入请求的时候,需要往这个端口上发送
http.port=:8888
rootUrl=’localhost:8888’ 这个是jar包运行时,前端的访问地址
allowHttpSideEffects=true Diffy 考虑到安全性,POST,PUT,DELETE 请求默认忽略,因此该参数为 true 则表示这三种类型请求仍能正常代理发送
summary.email=”xxx@xx” 对差异发送到指定邮箱
responseMode=primary 代理服务器是否返回结果,默认 (empty) 无返回,可指定 primary 返回线上版本,secondary、candidate