阿里云「飞天发布时刻」2024来啦!新产品、新特性、新能力、新方案,等你来探~ 了解详情
写点什么

Diffy:Twitter 的开源自动化测试工具

  • 2015-10-28
  • 本文字数:4001 字

    阅读完需:约 13 分钟

集成测试的挑战

随着软件系统的复杂性逐渐增加,微服务、面向服务的架构(Service-oriented architectures, SOA)等概念,越来越多的被应用到系统的设计当中,一同伴随的结果就是系统组件逐渐增加。

对于测试活动而言,最底层的单元测试,主要测试目标是单一的功能模块。它能够确保每个组件自身业务逻辑的正确性,但是随着系统组件依赖的增加,对单一模块的单元测试难度和成本都会上升。同时,单元测试覆盖率的提升,只能确保系统各个组件的正确性,组件之间的集成测试仍然是必不可少的。

传统集成测试的难点在于,对于每一个模块,都会有几个需要测试覆盖的分支,随着模块的增加,这些测试分支的组合,将会呈现几何级的增长(如图 1 所示)。

图 1:随着模块增加,测试复杂度指数级增加

Twitter 公司发布的自动化测试工具 Diffy ,就是为了降低开发人员对这种复杂系统的测试成本。

Diffy 简介

Diffy 是一个开源的自动化测试工具,它能够自动检测基于 Apache Thrift 或者基于 HTTP 的服务。使用 Diffy,只需要进行简单的配置,之后不需要再编写测试代码。

Diffy 主要基于稳定版本和它的副本的输出,对候选版本的输出进行比较,以检查候选版本是否正确。因此,Diffy 首先假设候选版本应该和稳定版本有“相似”的输出。即不论候选版本和稳定版本系统模块是否相同,他们的最终输出应该是“相似”的。

这里一直使用“相似”,而不是使用相同,这是因为相同请求可能会有一些 Diffy 不需要关心的干扰。比如:

  • 响应中包含服务器生成的时间戳
  • 代码中使用了随机数
  • 系统服务间有条件竞争

Diffy 有自己的噪声清理方式,确保这些噪声不会影响最终的结果。

Diffy 工作原理

在测试过程中,Diffy 充当一个代理,它能够将来源请求分发到不同版本的系统中去,通过对各个版本系统的输出进行对比,做出最终的结论。

Diffy 需要三个版本的系统,以实现它的噪声过滤和对比功能,它们分别是:

  1. 候选版本:该版本是待测版本,相对于生产环境版本有着跟新的代码
  2. 稳定版本:该版本通常是已经上线版本,或者是已知功能正常的版本
  3. 稳定版本副本:该版本是稳定版本的副本,和稳定版本运行相同的代码,主要用于排除噪声

整个运行流程为:

其中:

  • 原始区别为候选版本和稳定版本之间输出的区别,其中可能会包含上述的噪声
  • 噪声从稳定版本和其副本中获得,如果两个运行相同代码的系统输入相同输出却不同,则 Diffy 会认为这是开发人员不需要关心的噪声。

基于上述两个区别集合,Diffy 可以识别出候选版本和稳定版本真实的区别,这些区别很有可能就是一个缺陷。

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

示例

最后,通过 Diffy 仓库中的示例,来大致了解下 Diffy 的运行方式和过程:

步骤 1:克隆源码,并进行构建:

复制代码
git clone https://github.com/twitter/diffy.git
cd diffy
./sbt assembly

国内如果下载速度很慢,可以修改下 sbt 的镜像,使用国内的镜像:

复制代码
#cat ~/.sbt/repositories
[repositories]
local
osc: http://maven.oschina.net/content/groups/public/
oschina-ivy:http://maven.oschina.net/content/groups/public/,
[organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/
[type]s/[artifact](-[classifier]).[ext]
sonatype-oss-releases
maven-central
sonatype-oss-snapshots

步骤 2:启动候选服务。这里直接使用 example.sh,因此对应的候选服务地址为:http-candidate.herokuapp.com:80

步骤 3:启动基准服务(稳定版本)。这里直接使用 example.sh,因此对应的候选服务地址为:http-primary.herokuapp.com:80

步骤 4:启动稳定版本副本。这里对应的是:http-secondary.herokuapp.com:80

步骤 5:使用以下命令运行 Diffy(example.sh):

复制代码
java -jar diffy-server.jar \
-candidate='http-candidate.herokuapp.com:80' \
-master.primary='http-primary.herokuapp.com:80' \
-master.secondary='http-secondary.herokuapp.com:80' \
-service.protocol='http' \
-serviceName='My Service' \
-proxy.port=:8880 \
-admin.port=:8881 \
-http.port=:8888 \
-rootUrl='localhost:8888'

该命令指定了 Diffy 需要的三个版本对应的访问地址,同时在 8880 端口开启代理,8888 端口开启了结果访问服务。现在可以通过访问 8880 端口,Diffy 会将请求同时分发到三个版本的 http 服务上,然后记录这三个 http 服务的返回值。通过访问 8888 端口,就可以看见对这三个返回内容的对比结果。命令执行输出如下:

复制代码
coolex scala-2.11 # java -jar diffy-server.jar \
> -candidate='http-candidate.herokuapp.com:80' \
> -master.primary='http-primary.herokuapp.com:80' \
> -master.secondary='http-secondary.herokuapp.com:80' \
> -service.protocol='http' \
> -serviceName='My Service' \
> -proxy.port=:8880 \
> -admin.port=:8881 \
> -http.port=:8888 \
> -rootUrl='localhost:8888'
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
I 0908 13:09:41.130 THREAD1: HttpMuxer[/admin/metrics.json]
= com.twitter.finagle.stats.MetricsExporter(<function1>)
I 0908 13:09:41.189 THREAD1: HttpMuxer[/admin/per_host_metrics.json]
= com.twitter.finagle.stats.HostMetricsExporter(<function1>)
I 0908 13:09:41.393 THREAD1: /admin
=> com.twitter.server.handler.SummaryHandler
I 0908 13:09:41.394 THREAD1: /admin/server_info
=> com.twitter.finagle.Filter$$anon$2
I 0908 13:09:41.394 THREAD1: /admin/contention
=> com.twitter.finagle.Filter$$anon$2
I 0908 13:09:41.394 THREAD1: /admin/threads => com.twitter.server.handler.ThreadsHandler
I 0908 13:09:41.394 THREAD1: /admin/threads.json
=> com.twitter.server.handler.ThreadsHandler
I 0908 13:09:41.394 THREAD1: /admin/announcer
=> com.twitter.finagle.Filter$$anon$2
I 0908 13:09:41.395 THREAD1: /admin/dtab
=> com.twitter.finagle.Filter$$anon$2
I 0908 13:09:41.395 THREAD1: /admin/pprof/heap
=> com.twitter.server.handler.HeapResourceHandler
I 0908 13:09:41.395 THREAD1: /admin/pprof/profile
=> com.twitter.server.handler.ProfileResourceHandler
I 0908 13:09:41.395 THREAD1: /admin/pprof/contention
=> com.twitter.server.handler.ProfileResourceHandler
I 0908 13:09:41.395 THREAD1: /admin/ping
=> com.twitter.server.handler.ReplyHandler
I 0908 13:09:41.396 THREAD1: /admin/shutdown
=> com.twitter.server.handler.ShutdownHandler
I 0908 13:09:41.396 THREAD1: /admin/tracing
=> com.twitter.server.handler.TracingHandler
I 0908 13:09:41.396 THREAD1: /admin/events
=> com.twitter.server.handler.EventsHandler
I 0908 13:09:41.396 THREAD1: /admin/logging
=> com.twitter.server.handler.LoggingHandler
I 0908 13:09:41.397 THREAD1: /admin/metrics
=> com.twitter.server.handler.MetricQueryHandler
I 0908 13:09:41.397 THREAD1: /admin/clients/
=> com.twitter.server.handler.ClientRegistryHandler
I 0908 13:09:41.397 THREAD1: /admin/servers/
=> com.twitter.server.handler.ServerRegistryHandler
I 0908 13:09:41.397 THREAD1: /admin/files/
=> com.twitter.server.handler.ResourceHandler
I 0908 13:09:41.397 THREAD1: /admin/registry.json
=> com.twitter.server.handler.RegistryHandler
I 0908 13:09:41.403 THREAD1: Serving admin http on 0.0.0.0/0.0.0.0:8881
I 0908 13:09:41.478 THREAD1: Finagle version 6.28.0
(rev=de123b8f9d074c4e345ebd67e1a0e870bb921544) built at 20150827-162434
I 0908 13:09:43.010 THREAD1: networkaddress.cache.ttl
is not set, DNS cache refresh turned off
I 0908 13:09:43.507 THREAD1: Tracer:
com.twitter.finagle.zipkin.thrift.SamplingTracer
I 0908 13:09:43.810 THREAD1: zipkin-tracer
resolved to Addr.Bound, current size=1
I 0908 13:09:43.811 THREAD1: candidate resolved to Addr.Bound, current size=1
I 0908 13:09:43.811 THREAD1: primary resolved to Addr.Bound, current size=1
I 0908 13:09:43.811 THREAD1: secondary resolved to Addr.Bound, current size=1
I 0908 13:09:43.885 THREAD1: Scheduling com.twitter.diffy.workflow.
FunctionalReport at 2015-09-08 13:09:43 +0000

步骤 6:发送一些请求,让 Diffy 来记录和分析:

复制代码
curl localhost:8880/json
curl localhost:8880

步骤 7:通过 localhost:8888 查看结果:
可以看见刚才访问的两个地址都已经被记录,同时由于第二个地址增加了时间戳,所以原始对比结果认为他们是不相同的。

(点击放大图像)

点击对比失败的地方,可以展示出两次对比不同之处:

(点击放大图像)

可以看见,该请求两个版本的不同是由时间戳导致的。如果选择“排除噪声”,那么最终结论会变成相同。

(点击放大图像)


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-10-28 18:4310509

评论

发布
暂无评论
发现更多内容

HarmonyOS后台任务管理开发指南上线!

HarmonyOS开发者

HarmonyOS

Clop Pro for mac(图片优化工具)v2.4.0激活版下载

影影绰绰一往直前

华为云耀云服务器L实例多重防护助力企业放心上云

YG科技

数据库系统概述之国产数据库

小齐写代码

华为云三重优惠!云耀L实例轻松应对挑战,助您企业更高效上云

YG科技

Programming Abstractions in C阅读笔记:p202-p234

codists

8. 业务中台架构

Joy

Dropzone 4 for mac(文件拖拽增强工具)v4.80.0激活版

影影绰绰一往直前

多功能视频播放器Infuse中文激活版最新

mac大玩家j

Mac软件 视频播放器 音视频工具

OpenHarmony Meetup 2023北京站圆满举办

OpenHarmony开发者

OpenHarmony

云游戏迎来新时代,华为云轻应用服务器引领数字化创新

YG科技

A16Z领头的Story Protocol有什么看点?

币离海

BRC20 Story Protocol

兴湘集团司库管理平台成功上线,打造国企数智管理新标杆!

用友BIP

企业数智化

Keka for Mac(压缩解压工具) 1.3.6中文版

展初云

Mac 解压缩软件 Keka

Royal TSX 6 for Mac远程管理软件

展初云

Mac软件 远程桌面管理

简单上云第一步的华为云服务器,助力中小企业提升业务

平平无奇爱好科技

华为云耀云服务器L实例:创新的解决方案,推动小程序与网站开发新趋势

YG科技

比特币首次减半11 周年:从 12 美元涨至 37,000 美元

币离海

BTC 减半

Mitti for Mac(视频回放编辑工具)v2.5.6激活版

影影绰绰一往直前

Mac电脑PDF 批量处理软件:BatchOutput PDF激活版

胖墩儿不胖y

Mac软件 pdf处理工具 好用的PDF编辑器

高性能云计算,华为云服务器行业遥遥领先

平平无奇爱好科技

NGINX 和 NGINX PLUS 缓存指南

NGINX开源社区

nginx 性能优化 NGINX PLUS 缓存调优 分割缓存

office办公套件:Office LTSC 2021 for Mac v16.81 beta版

加油,小妞!

office办公套件 办公套件 Microsoft office

SmartSVN for Mac(SVN客户端)v14.4激活版

影影绰绰一往直前

Dropzone 4 for Mac(文件拖拽操作增强工具)

展初云

效率工具 Mac Dropzone 4

INFINI Gateway 与华为鲲鹏完成产品兼容互认证

极限实验室

Gateway 极限科技 华为鲲鹏认证

华为云耀云服务器L实例,助力企业开启轻松云计算之旅

YG科技

华为云耀云服务器L实例:在小程序竞争中的强大利器

YG科技

CI/CD 构建中能保护好 SSHKEY吗?

极狐GitLab

DevOps SSH CI/CD SSH Key

Kubernetes 漫游:kube-scheduler

Phoenix

云原生 kubernetes 运维

苹果电脑压缩解压工具:Keka for Mac中文版

加油,小妞!

Keka Mac 压缩解压工具

Diffy:Twitter的开源自动化测试工具_语言 & 开发_金灵杰_InfoQ精选文章