干货时间:聊聊DevOps下的技术系列之契约测试
摘要:本期和大家简单聊聊在服务交互场景下使用服务契约的重要性,以及契约管理的必要性,最后简单介绍了下契约测试。
1、服务交互带来的问题
在上一篇文章中,我们系统的列举了DevOps各个流程中常用的测试技术。
接着上一篇的图,我们简单画下一个系统应用的内部服务的调用关系:交付一个大的系统可能涉及到多家ISV进行集成,每家ISV自己又存在前端、网关、后端等多个微服务,且各自ISV或者服务均存在自己的SE、开发和测试人员,都有自己相对独立的版本演进,服务之间存在调用关系。
思考一下,这会带来哪些问题呢?
- 通过接口文档或者表格管理接口内容,服务交互双方、多方频繁对接交互调用的接口信息,频繁刷新,剪不断、理还乱,让人崩溃。
- 服务依赖导致必须等待底层服务先开发完成才能联调对接和集成测试,效率低下;
- 此时如果发现被调用服务接口不满足要求、接口缺失、接口无法联调等问题时,需要重新等待版本联调,造成资源和时间上的浪费;
- 服务都在不停的向前演进,调用服务与被调用服务的版本会随着外部需求增加、Bug修改、代码重构等等因素而导致接口发生变更,接口调用服务往往无法及时获取接口变化而导致整体业务受损。
2、服务契约--服务交互问题的一种解决方案
如何解决服务间纷纷复杂的联调问题呢?本章节我们来聊一聊契约与契约测试。
顾明思义,契约就是一份由双方或多方共同订立的、具有强制遵从性的信用文书。契约测试全称消费者驱动契约测试(Consumer Driven Contracts Testing),最早见于2011年。“消费者驱动契约测试”名称中清楚描述了“契约”、“谁提供契约”的问题。
一般来说,是消费者(Consumer)把自己对输入和输出的数据结构、性能已经并发性等期望以约定的格式告诉服务提供者(Provider),服务提供者签署同意,这就形成了一份服务契约,服务提供者对所有消费者的契约取并集进行服务能力开发,形成自己服务的对外承诺或者schema。
模型如下:消费端服务 A、B、C 调用访问服务提供端服务A,消费端服务 A、C服务提供端服务B。服务提供端会根据消费端期望分别生成1份契约文件,以满足消费端的诉求。
服务之间通过契约交互会带来哪些好处呢?
1)、使用契约,接口调用双方的对接、问题定界等都有“法律依据”,问题不会扯不清、道不明、来回甩锅。
2)、使用契约,就确定了交付双方的接口形式和入口与出口期望,消费端和服务提供端可以并行开发服务,并且在开发过程中就利用契约进行预集成测试,不需要等待联调再来集成测试,大幅降低联调沟通成本。
3)、因为契约的存在,可以整体看到服务消费端的原有接口使用情况,让接口的变动有迹可循,即使变动也可以确保变动的安全性和准确性。
4)、消费端也能通过契约的变化获知服务端的API变化情况
3、契约交互的问题
在第二章节我们看到契约的基本流程。在正常的契约测试流程中,契约由消费者提供,服务者遵从,根据消费者的提供的契约完成服务测试。但是,大家思考下这种模式存在什么样的问题?我们思考下一下的问题:
- 双方的契约有了,但是口头协议空口无凭,契约如何存储,以及如何才能防篡改?
- 邮件交互、会议纪要难以维护?
- 在敏感市场,消费者提供的契约是否符合正常诉求与合规?
- 在多ISV服务商、多部门协作的应用系统,消费者频繁刷新契约要求怎么办?
- 正常需要刷新契约怎么处理、契约怎么会退或者回溯?
- 消费端驱动,会不会造成消费端权力过大,话语权过重,倒逼服务提供端,最终也会导致整个系统不伦不类?
从上面的几个问题可以看出,由于契约很重要,那么设计和管控契约也就显得更加重要。
4、契约设计与契约管理的必要性
交互的问题并不像想象的那边简单,为了解决契约设计和管控的问题,我们新增一个设计管控和契约管理的环节。
设计管控环节类似于议会这种机沟通和决策机构,用于调停和审视契约的合理性、合规性和更改的必要性,且对于多消费者的契约做合并处理。
契约管理环节,解决契约存储、访问认证和不可篡改性、可追溯性和可回退等问题。这样就避免了前面所说的问题,当然牺牲了一定了灵活性,但是在大型系统中,这样行为是值得的。
我们看下,消费者的契约的生成和下载过程就变成如下流程:
同时,如果服务端要主动变更契约,也要得到消费端和审视委员会的通过,审核通过合入后,消费者和服务提供者从契约管理平台下载契约使用。流程变得如下:
5、契约测试
前面的章节,我们花了较多篇幅介绍了契约的生成和契约在服务交互过程中的作用以及重要性,那么对契约的测试也很重要。下面我们简单聊聊如何对契约进行测试。
契约测试不是组件测试,契约测试和核心也是通过API来进行。每个消费者只会关注自己的期望是否得到满足,所以只需要根据自己提供的、已审核通过的契约文件进行测试。而服务提供端则需要满足所有消费者的诉求,需要拿所有消费者的契约做测试,所有契约需要测试通过。如下所示:
由于实际开发中,契约签订之后,Consumer和Provider是同步开发,所以Consumer和Provider也是分别测试。一般的契约测试过程如下:
Consumer服务的测试环境,需要使用契约进行Mock Provider服务进行构建:
Provider服务的测试环境,则需要根据和Consumer签署的契约文件生成的契约测试用例进行测试,通过测试契约用例验证自己提供的接口是否满足消费者需要,接口是否有变更。一旦接口发生变更,契约测试用例会执行失败。
前面所述,契约是消费者(Consumer)把自己对输入和输出的数据结构、性能已经并发性等期望以约定的格式告诉服务提供者(Provider),服务提供者签署同意后形成的,那边契约测试的主要内容也便是这几个方面:
支持契约测试的工具有Pact、Pacto、Janus、CloudTest,Swagger也能满足部分要求。一般来说,业界使用Pact工具的较多,简单说下Pact工具的过程,具体Pact用法请参照官网:
Consumer测试:
Provider测试:
我们也补充下Pact工具的优缺点
6、微服务下的服务契约样例
契约一般是一个yaml文件或者json文件的格式,我们以CSE微服务的契约为展示样例:
结语:本期和大家简单聊聊在服务交互场景下使用服务契约的重要性,已经契约管理的必要性,最后简单介绍了下契约测试。契约测试工具用法的指导文档较多,本篇没有做展开。DevOps下,契约测试也是需要集成到流水线中,欢迎下来继续交流。
本文分享自华为云社区《聊聊DevOps下的测试技术(2)聊聊契约与契约测试 》,原文作者:柳哥说 。