Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【洞见荐书】| 《深度实践微服务测试》(文末赠书)

【洞见荐书】| 《深度实践微服务测试》(文末赠书)

作者头像
ThoughtWorks
发布于 2022-08-26 06:20:18
发布于 2022-08-26 06:20:18
6420
举报
文章被收录于专栏:ThoughtWorksThoughtWorks

距离我上一次写契约测试的文章已经过去了三年,在这期间,契约测试在测试策略层面已经确确实实地被很多团队落地实践,无论是对工具的熟练层度、还是对引入契约测试的主观意愿,越来越多的团队在契约测试上都展现出了更高的使用水准,甚喜。

最近,我接触到了两个不同项目的一些事情,它们都对契约测试有所涉及,但又都包含了一些很容易让人迷失的细节,所以想和大家一起分享。

生产者端的契约测试不是“写”出来的

在一次帮助项目上的开发同学评审契约测试代码的时候,我留意到开发同学多次描述“……在生产者端的实现是这么写的……” ,我顿时感到有些“好奇”,因为正常情况下,Pact在生产者端的契约测试不是写出来的,而是执行出来的(否则“消费者驱动的契约测试”的最终结果就只能是累死生产者团队)。于是我们进一步地对生产者端的契约测试代码进行了走读。

结果发现,开发同学通过注解的方式、使用Pact的state功能对契约文件中定义的每一个交互分别进行了对应响应的实现。这样就会出现“契约文件定义多少交互,生产者端就要写多少测试”的情况,显然,这不是一种最佳的契约测试实践方式。

我们先来回顾一下契约测试在生产者端的一般实践方式,如下图所示,Pact从Pact Broker拉取契约文件(或者直接读取本地的契约文件),然后从契约文件中提取交互中的请求发送给生产者服务,生产者服务根据请求返回对应的响应,Pact再将生产者返回的真实响应与契约文件中定义的期望响应进行对比,得出测试结果。在这一过程中,生产者端的契约测试有两个重要特征:

  • 生产者端只需要执行测试,而不需要写测试,测试案例都由Pact通过契约文件来触发执行;
  • 测试执行过程中,要求生产者服务一定要是尽量真实的服务;

这里的“真实”又体现在两个点上,其一,服务一定要是真正部署且运行的服务;其二,服务的代码一定(或尽量)要贴近真实产品的源码,避免包含或使用支持测试的辅助代码,即测试尽量保证非侵入性。

而Pact提供的state方式,恰恰是一种侵入式的测试方式。通常来讲,当消费者端期望测试一些异常情况下的交互时,可以和生产者端协商使用state来支持测试,比如测试生产者服务出现Internal Server Error的情况,这些情况在正常的测试环境中很难稳定触发,不能支持测试的持续执行,所以才会使用state的方式来“模拟”。所以,作为一种侵入式的模拟测试手段,state方式在契约测试中一定要慎用。

那么,回过头来想一下,为什么开发同学会在生产者端的契约测试中地毯式地使用state呢?我想可能还是对契约测试的理解有些流于表面造成的。通常情况下,当我们说到“写测试”的时候,头脑中的步骤大概是这样的:

  1. 分析和思考测试点;
  2. 把测试案例写下来;
  3. 执行测试;

而在使用Pact进行消费者驱动的契约测试时,特别是在生产者端,“分析和思考测试点”的工作显然是不需要的,因为已经有契约文件这个现成的测试集合了,那么要做的就是“写测试案例”和“执行测试”。怎么写?对于生产者端的契约测试,Pact官网并没有给出多少写的步骤(因为确实在生产者端,通常情况下就不需要写测试),唯独要写的就是state的方式。由此,可能会误导一些开发同学以为生产者端的契约测试就是根据契约文件的定义使用state来遍地开花,实则不然。

生产者端的契约测试要使用Mock吗?

还是在上述对生产者端的契约测试进行评审的过程中,我们发现生产者端的state之所以“很香”,一个非常重要的原因就是方便构造数据。我们上面提到,state的主要使用场景是模拟生产者服务出现异常情况的响应,异常情况都可以模拟,那正常情况的响应岂不更是顺手拈来。以SpringBoot的Controller、Service、Repository三层划分来说,既然能在Service层(甚至Controller层)使用Mock返回任意数据的响应,那何必还去调用依赖服务或者查询数据库然后组装真实数据返回呢?毕竟对测试来说,测试数据的准备和保障永远都是令人头痛的事情,这对契约测试来说也不例外。所以,在“真香定律”面前,state + Mock就成了生产者端执行契约测试的最佳组合......貌似。

这样的认知有一个看似无懈可击的“理论支撑”,那就是:“契约测试验证的只是生产者服务返回的数据结构(少量情况下可能也会校验数值),通俗来讲就是schema,既然只验证schema,那生产者服务内部的数据是Mock的还是E2E的,其实并不重要”。如此考量,可能也是对契约测试的认知流于片面所致。作为契约测试众多价值中的一种:验证生产者服务的履约能力,期望的一定是最真实的生产者服务,能够E2E就尽量E2E,能不使用Mock就尽量不使用Mock,只有这样,我们验证的履约能力才是最接近真实的履约能力。实施自动化测试的目的,不是让测试能永远顺利通过,而是让测试能永远体现出其应有的价值。

当然,理想很丰满,但现实却很骨感。在实践过程中,我们确实难免会遇到依赖服务不稳定、测试数据难以构造等问题。这种时候,我们首先应该考虑的是使用虚拟服务(比如wiremock)和测试数据库(比如testcontainers),而不是通过state在生产者服务内部添加Mock代码,因为前者在解决数据依赖的同时保证了生产者服务自身的完整性和真实性,而后者则是外科手术式的侵入式实现。而当虚拟服务和测试数据库都无法满足我们的需求时,比如就是需要构造Internal Server Error的情况,那么就大可使用state + Mock的组合了。

换个角度看契约测试

通常情况下:

  • 我们都是在服务之间讨论契约测试,典型的场景就是在微服务之间构建契约测试;
  • 契约测试要想发挥最大的价值,一定是在多(消费者)对一(生产者)的架构中;

然而,这两点也有例外。前段时间帮助另一个项目解析测试痛点时,就遇到了一个非常鲜明的案例。如下图所示,一个APP前端消费后端的API服务,甚至可以把后端的API服务理解为APP专属的BFF。对于这样的架构(其实这里都谈不上“架构”,仅仅算个调用关系罢了),通常我们是完全不用考虑做契约测试的,因为如此架构下的契约测试并不能带来多余UI E2E测试与API功能测试的任何价值。

然而,这个项目的痛点在于,在生产环境上要求可以同时共存不同版本的APP,BFF需要对历史版本的APP进行前向兼容。不同版本的APP在消费BFF时使用的接口定义可能不同,这就要求团队在每次更新BFF版本时,都要对所有历史版本的APP做回归测试,以避免出现接口不兼容的情况。显而易见,这个测试工作量是很大的,即使通过UI的E2E自动化测试来全回归,测试执行和维护的工作量也是远远超出了我们通常基于测试金字塔所期望的可控范畴。可如果我们换个视角来看待这个问题,如下图所示,将APP的不同版本视为各自不同的消费者服务,BFF还是那个唯一的生产者服务,那整个架构不就是我们前面提到的最经典的契约测试场景了吗?

所以,只要我们能够建立既往各版本APP与其当时版本BFF之间的完整契约测试,我们就能为BFF的后续迭代变更提供强有力的质量保障,从而避免了每次更新BFF都要回归测试各个历史版本APP的艰难挑战。

说到这里,细心的同学可能会想,“UI的E2E自动化测试解决不了这个问题的根本原因是工作量太大,契约测试能够解决这个问题无非是因为测试维护和执行的工作量小而已,那么类似的,不用契约测试,而用API功能测试的方法,为各个版本的APP所消费的后端BFF版本建立各自的自动化API功能测试,是不是也能解决这个问题呢?” 答案是肯定的,建立多套自动化API功能测试确实可以解决相同的问题。那它和契约测试的区别又在哪里呢?答案就是没有区别。在这个场景下,当我们使用Pact进行契约测试时,其实质也是使用不同的契约文件触发了不同的版本的API测试。而当我们抛开Pact这个工具,使用类似RestAssured这样的工具来实现类似的“多套”API自动化测试时,我们达到的效果和使用Pact是几乎完全相同的。其实,当我们真的构建这种多套API功能测试时,我们所做的工作就是使用RestAssured对契约测试进行了实现。所以说,契约测试更重要的是一种思想,当我们剖析完问题的实质、确定可以使用契约测试来解决问题后,选择怎样的工具是可以非常灵活的。

以上即为我在最近工作中遇到的一些关于契约测试的真实思考,潦以叙之。当然,这里我没有对很多细节进行阐述,比如什么是契约测试、如何做契约测试、什么是虚拟服务等等,对于这些技术细节,感兴趣的朋友可以关注阅读我和其他三位资深Thoughtworker合著的《深度实践微服务测试》一书(算是一个小小的广告吧)。

《深度实践微服务测试》内容来源于4位作者服务多个大中型知名企业后总结的微服务测试方法论与实战经验,内容翔实、鲜见。全书涵盖测试策略、接口与界面自动化测试、契约测试、性能测试、微服务监控、服务虚拟化混沌工程安全测试。一本书破解当下测试工作的众多难题,可为微服务和分布式系统的质量保障提供一站式解决方案。 关于测试,你们有怎样的思考?欢迎在评论区回复。我们将为评论区回复中点赞最多的前3名读者分别赠送一本《深度实践微服务测试》。 识别下方二维码,前往商品页查看详情。


- 相关阅读 -

读书雷达4.0书目推荐——技术观察篇

「洞见荐书」| 《掌握分布式跟踪》(文末赠书)

点击【阅读原文】可前往商品页查看详情。

本文版权属Thoughtworks公司所有,如需转载请在后台留言联系。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ThoughtWorks洞见 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Tomcat 安装和简单使用
ApacheTomcat 是 JakartaEE (正式的 JavaEE)技术的一个子集的开放源码软件实现。ApacheTomcat 的不同版本可用于规范的不同版本。规范和相应的 Apache Tomcat 版本之间的映射如下:
acc8226
2022/11/16
7510
Tomcat 安装和简单使用
Tomcat配置
    Tomcat是轻量级的Web应用服务器,可以从官网http://tomcat.apache.org下载最新的Tomcat服务器版本。下载完成后直接解压Tomcat文件到指定的目录下。
Tacc
2022/05/05
1K0
Tomcat_总结_02_单机多实例
上图中的 CATALINA_HOME 指Tomcat安装路径,CATALINA_BASE 指实例所在位置。 CATALINA_HOME 路径下只需要包含 bin 和 lib 目录,而 CATALINA_BASE 只存放 conf、webapps、logs 等这些文件,
shirayner
2018/08/10
3460
Tomcat_总结_02_单机多实例
谈谈tomcat引起的中文乱码问题
平时在使用tomcat做一些服务的时候经常遇到各种乱码问题,要么是控制台输出乱码或者输出日志乱码,要么页面接收乱码,非常烦人。引起乱码的原因多个,从网上学习了很多,现在尝试简单总结给大家分享
用户5521279
2019/06/02
22.7K0
Web基础配置篇(三): tomcat的配置及使用
tomcat,大家应该都知道是啥,servlet的Web容器而已,遵守servlet规范的JavaEE服务器。我们通常用tomcat来部署war包来做应用服务器。
品茗IT
2019/09/11
5780
Tomcat的源码分析
总结 : 由上面摘抄的主要源码可知 ,在catalina.bat 启动时 ,主要是加载了一个叫bootstrap.jar 的jar包 . 在加载这个jar 以后 ,他又运行了这个 jar 下面的org.apache.catalina.startup.Bootstrap 这个类, 通过set ACTION=start 启动他的main方法 ,完成对Tomcat的启动
时间静止不是简史
2020/07/24
9850
Tomcat的源码分析
Tomcat启动一闪而过就消失的原因和解决方法
Tomcat启动一闪而过怎么办?这成为了许多刚接触tomcat开发环境工作者的一个大问题,许多用户朋友都不知道是因为什么问题导致出现这种情况,下面就一起来了解一下吧。
全栈程序员站长
2022/06/25
2.1K0
Tomcat启动一闪而过就消失的原因和解决方法
Tomcat
JavaWeb 是指,所有通过 Java 语言编写可以通过浏览器访问的程序的总称,叫 JavaWeb。
一个风轻云淡
2022/11/15
1.1K0
Tomcat
tomcat详细安装及配置教程_tomcat安装及配置
2、Download下边的版本,这里最新的是10.0x,但是一般不选最新版本,我选择的是8.5x,所以点击Download下边的Tomcat 8
全栈程序员站长
2022/10/02
8200
tomcat详细安装及配置教程_tomcat安装及配置
Java开发环境系列:一篇能帮你解决99%线上问题的Tomcat排雷日记
下载地址:https://archive.apache.org/dist/tomcat/
架构师小跟班
2019/08/06
9220
Java开发环境系列:一篇能帮你解决99%线上问题的Tomcat排雷日记
Java知识:(3)Tomcat
压缩版:window(rar,zip) linux(tar,tar.gz)学习时候使用
py3study
2020/01/08
6130
Java知识:(3)Tomcat
Tomcat
Tomcat服务器由Apache提供,开源免费。由于Sun和其他公司参与到了Tomcat的开发中,所以最新的JSP/Servlet规范总是能在Tomcat中体现出来。当前最新版本是Tomcat8,我们课程中使用Tomcat7。Tomcat7支持Servlet3.0,而Tomcat6只支持Servlet2.5!
eadela
2019/09/29
1.5K0
Tomcat
【JavaEE WEB 开发】Tomcat 详解 Servlet 入门
转载请注明出处 :  http://blog.csdn.net/shulianghan/article/details/47146817
韩曙亮
2023/03/27
3630
【JavaEE WEB 开发】Tomcat 详解 Servlet 入门
tomcat 9.0.4 性能调优
参考了网上的一些优化参数,但是在启动中发现 有2个报错: 11-Feb-2018 15:57:23.293 警告 [main] org.apache.catalina.startup.SetAllPropertiesRule.begin [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'maxSpareThreads' to '200' did not find a matching property. 11-Feb-2
拓荒者
2019/03/15
5410
Tomcat配置环境变量
Tomcat是目前比较流行的开源且免费的Web应用服务器,在我的电脑上第一次安装Tomcat,再经过网上教程和自己的摸索后,将这个过程 重新记录下来,以便以后如果忘记了可以随时查看。
全栈程序员站长
2022/08/19
1.9K0
Tomcat配置环境变量
Tomcat讲解
点击startup.bat启动失败,我就用cmd命令打开,发现是没有JAVA_HOME 环境。这是因为电脑上没有配置JAVA_HOME或者JRE_HOME导致的
Albert_xiong
2021/06/21
8010
Tomcat讲解
【Java框架型项目从入门到装逼】第三节 - 如何用Tomcat发布web项目?
啥叫Tomcat?有道词典是这么说的。 image.png 这个我们姑且不管,实际上呢,Tomcat是一种Web服务器,我们自己做好了一个Web项目,就可以通过Tomcat来发布。服务器呢,又分为硬件
剽悍一小兔
2018/05/17
9050
Tomcat 的安装与环境配置教程(超详细)
1、下载Tomcat1>官网:Apache Tomcat® - Apache Tomcat 9 Software Downloads这里我选择的是Tomcat9.0  64bit   Windows(作为示例安装)(如图紫色框中所示)---自行下载安装
楠羽
2022/11/18
35.5K0
Tomcat 的安装与环境配置教程(超详细)
Tomcat服务器
不论是我们一开始做的java桌面程序、控制台程序以及socket gui界面程序(这个我还没学),都是服从Javase规范的。接下来我们要学习的将是Javaweb程序,服从javaee规范。 目前的软件有两种,一是C/S(客户端—服务器)模式,向像我们常用的QQ这一类的软件,这类软件要求我们必须下载客户端,而且还随着服务器的迭代而升级。另外一种就是B/S(浏览器–服务器)模式,比如你现在浏览的CSDN我的博客,也就是大多数的网站都是这种模式的,所以我们只需要有一个浏览器就行了。而且有一个和C/S程序相反的优点,就是我们不必在服务器升级之后升级浏览器了。 Javaweb的程序就是B/S结构的。
roobtyan
2019/02/21
1.8K0
Tomcat 快速入门
Tomcat 快速入门 版本说明 本文使用 Tomcat 版本为 Tomcat 8.5.24。 Tomcat 8.5 要求 JDK 版本为 1.7 以上。 简介 Tomcat 是什么 Tomcat 是由 Apache 开发的一个 Servlet 容器,实现了对 Servlet 和 JSP 的支持,并提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台、安全域管理和Tomcat阀等。 由于 Tomcat 本身也内含了一个 HTTP 服务器,它也可以被视作一个单独的 Web 服务器。但是
静默虚空
2018/03/16
1.5K0
Tomcat 快速入门
相关推荐
Tomcat 安装和简单使用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档