如何用Pact进行微服务集成测试
原文链接
https://codefresh.io/docker-tutorial/how-to-test-microservice-integration-with-pact/
挑战:微服务集成测试
迁移到微服务对测试我们的系统产生了新的挑战。理论上每个微服务都应该是隔离的并可以独立操作。但在实践中一个服务如果没有其他部分通常没什么用。另一方面 - 为一个服务拉起整个系统的拓扑进行测试抵消了微服务期望带来的模块化和封装。
挑战在于如何检验与其他服务集成后没有问题。我们希望越早越好。而且我们不想将复杂的生产环境重现一遍。一般来说这种检验是集成功能测试或叫端到端测试。但实际是当我们的系统越来越复杂 - 端到端带来的收益越少。 大量的相互依赖导致误报和很长的执行周期。 使得测试变得很难管理与调试。
这甚至有一个测试金字塔理论(最初由Mike Cohn在他的著作‘Succeeding with Agile’中提到)讲述了为了优化你的投入,你需要更少的高层次的端到端测试,写更多的低层次的单元测试。
请阅读本文并看看Codefresh(https://codefresh.io/codefresh-signup/?utm_source=Blog&utm_medium=Post&utm_campaign=pactT), 他是对于Docker最好的CI。

单元测试很好!但在它带来的所有收益中 - 他们对测试与其他服务的集成没什么作用。
那我们怎样保证每个服务团队可以独立的迭代但又能保证整体系统的健康呢?我们如何实现持续交付,小批量生产,快速反馈,而又不会在每次变更时引起服务出问题呢?
一个可能的答案是Consumer-Driven Contract(CDC) 测试。这种测试策略是基于一种多年前就定义的服务进化模式。它现在分布式系统变得更常见后变得更适合了。
Consumer-Driven Contracts:
我尝试简单解释一下。 Consumer-Driven Contracts实际就是面向服务与服务关系的合约。意思就是不想以前是provider提供方定义接口与服务级别是什么样(同事消费者consumer尽量适配) - 现在消费者来领舞。 每个消费者来定义它期望服务提供方需要交付与需要检查的。这就将集成的责任转移到服务提供方。
那就变成以下流程:

在商务合约上者通常描述成‘将消费者放在第一位’ 或‘倾听你的客户’。因为想要提供最好的服务我们需要尽量做到客户期望和需要的。而不是我们假设对的事。
当讨论微服务进化时 - 在那种每个服务都有一个独立团队开发的大型企业里尤其重要。有时这些团队也可能在不同的地理位置和区域。这影响了即时沟通和让业务功能进化更有挑战性。
合约测试框架
消费者驱动合约当然可以通过投资团队间的沟通与协作来管理。 也可以通过使用结构化的系列化格式如protobuf,thrift或messagepack消息体来解决。但如果要管理一个定义好的流程 - 最好使用框架,尤其如果是个开源的。
这种框架已经出现了。这其中最杰出和活跃的是Pact和Spring Cloud Contract。后者只针对使用JVM的项目。 而Pact使用Ruby写的但可以支持很多语言,包括Java,Go,Python,Javascript。 让它很适合在复杂,多样性的微服务系统中使用。
今天我们会看看如何在两个服务间定义和校验合约。消费者服务是用Python写的。而提供方服务是用Go写的。测试会在我们的CI/CD流程中进行 - 也就是在Codefresh流水线里面。
Pact
所以,Pact怎么工作的?它开始于消费者。
消费者服务的开发写一个测试。测试定义了与提供方的集成。这包括了提供方需要的状态,请求的消息体和期望的结果。基于这个定义Pact建立和运行一个提供方的桩来进行测试。这个测试的输出回事一个或多个json文件,一般是这样的:
{
"consumer": {
"name": "billy"
},
"provider": {
"name": "bobby"
},
"interactions": [
{
"description": "My test",
"providerState": "User billy exists",
"request": {
"method": "POST",
"path": "/users/login",
"headers": {
"Content-Type": "application/json",
},
"body": {
"username":"billy",
"password":"issilly"
}
},
"response": {
"status": 200,
}
},
],
"metadata": {
"pactSpecification": {
"version": "2.0.0"
}
}
}
这就是合约,这就是pact。 现在他们被传给服务提供方。也可以被提交给共享的git仓库,或通过Pact Broker应用上传到共享的文件存储。
一旦合约更新过了 - 提供方需要对其进行测试验证是否仍符合要求。它通过使用共享的pact文件运行它自己的校验测试而不是真实版本的服务。如果所有的交互是符合预期的并测试通过了 - 我们就可以继续了。 如果不 - 提供方的开发需要通知消费方的开发。然后,他们可以一起分析什么导致了合约的失败。
本文来自微信公众号「麦芽面包,id「darkjune_think」
转载请注明。微信扫一扫关注公众号。
交流Email: zhukunrong@yeah.net

如何用Pact进行微服务集成测试的更多相关文章
- PACT 在微服务架构中的用途是什么?
PACT 是一个开源工具,允许测试服务提供者和消费者之间的交互,与合同隔离, 从而提高微服务集成的可靠性. 微服务中的用法 用于在微服务中实现消费者驱动的合同. 测试微服务的消费者和提供者之间的消费者 ...
- idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制
摘要 使用 Istio 可以很方便地实现微服务间的访问控制.本文演示了使用 Denier 适配器实现拒绝访问,和 Listchecker 适配器实现黑白名单两种方法. 使用场景 有时需要对微服务间的相 ...
- CODING DevOps 系列第五课:微服务测试——微服务下展开体系化的微服务测试
微服务测试的痛点与挑战 这张图可以形象地展示单体服务和微服务的对比,单体应用就像左边巨大的集装箱,软件模块和应用都包括其中:而微服务就像是由一个小集装箱组成,微小的服务组成一个庞大.完整的系统.单体服 ...
- 使用 Spark 进行微服务的实时性能分析
[编者按]当开发者从微服务架构获得敏捷时,观测整个系统的运行情况成为最大的痛点.在本文,IBM Research 展示了如何用 Spark 对微服务性能进行分析和统计,由 OneAPM 工程师编译整理 ...
- 85道Java微服务面试题整理(助力2020面试)
微服务 面试题 1.您对微服务有何了解? 2.微服务架构有哪些优势? 3.微服务有哪些特点? 4.设计微服务的最佳实践是什么? 5.微服务架构如何运作? 6.微服务架构的优缺点是什么? 7.单片,SO ...
- 如何用ABP框架快速完成项目(11) - ABP只要加人即可马上加快项目进展- 全栈篇(2) - 不推荐模块组件化, 推荐微服务
一个人写代码不需要担心会和别人的代码冲突, 不需要做代码合并, 不需要担心自己的代码被覆盖. 但是多个人一起写代码就需要担心这些问题. 解决这些问题的方法很多, 比如用AzureDevOps(TF ...
- 如何用ABP框架快速完成项目(7) - 用ABP一个人快速完成项目(3) - 通过微服务模式而不是盖楼式来避免难度升级和奥卡姆剃刀原理
这节文章十分重要!十分重要!十分重要! 很多同学在使用ABP的过程中遇到很多问题, 花费了很多时间和精力都还无法解决, 就是卡在这节文章这里. Talk is cheap, just show ...
- 教你如何用Nginx搭建一个安全的、快速的微服务架构
今天我们要谈论微服务以及如何使用Nginx构建一个快速的.安全的网络系统.最后,我们将向您展示一个使用Fabric模式如何非常快速和轻松地构建一个微服务的demo. 在我们探讨Fabric模式之前,我 ...
- 微服务下的契约测试(CDC)解读
1. 前言 有近两周没有在公众号中发表文章了,看过我之前公众号的读者都知道,公众号中近期在连载<RobotFramework接口自动化系列课程>,原本计划每周更新一篇,最近由于博主在带一个 ...
随机推荐
- 缓冲&缓存&对象池概念的理解
一).缓冲 作用:缓解程序上下层之间的性能差异. 1).当上层组件的性能优于下层组件时加入缓冲机制可以减少上层组件对下 层组件的等待时间. 2).上层组件不需要等待下层组件接收全部数据,即可返回操作, ...
- 在UEFI+GPT下使用rEFind实现Win10 + Kali2.0 双引导
转载自:在UEFI+GPT下使用rEFind实现Win10 + Kali2.0 双引导 https://www.linuxidc.com/Linux/2016-07/133717.htm
- C#Windows Forms (Demo.SYS)--xdd
private void Show_background_picture()//随机更换背景 { ";//默认值 Random ran = new Random(); , );//返回一个1 ...
- CentOS 7 Keepalive 脚本不执行解决
目录 问题 问题一 括号问题 问题二 脚本名称问题 问题 起因是在测试部署 Altls + Keepalive 高可用读写分离,测试停止Atlas服务的时候,发现Keepalive不会自动主从切换,就 ...
- ThinkPHP5——模型关联(一对一关联)
定义 定义一对一关联使用了hasOne,hasOne方法的参数包括: hasOne('关联模型名','外键名','主键名',['模型别名定义'],'join类型'); 下面定义一个用户表,公司给每个用 ...
- 开发者如何学好 MongoDB
作为一名研发,数据库是或多或少都会接触到的技术. MongoDB 是当前火热的 NoSQL 之一,我们怎样才能学好 MongoDB 呢?本篇文章,我们将从以下几方面讨论这个话题: MongoDB 是什 ...
- .Net Core使用Ocelot网关(一) -负载,限流,熔断,Header转换
1.什么是API网关 API网关是微服务架构中的唯一入口,它提供一个单独且统一的API入口用于访问内部一个或多个API.它可以具有身份验证,监控,负载均衡,缓存,请求分片与管理,静态响应处理等.API ...
- KubeSphere 日志备份与恢复实践
为什么需要日志备份 KubeSphere 日志系统使用 Fluent Bit + ElasticSearch 的日志采集存储方案,并通过 Curator 实现对 Index 的生命周期管理,定期清理久 ...
- 【强化学习】DQN 算法改进
DQN 算法改进 (一)Dueling DQN Dueling DQN 是一种基于 DQN 的改进算法.主要突破点:利用模型结构将值函数表示成更加细致的形式,这使得模型能够拥有更好的表现.下面给出公式 ...
- React、React Native面试题
1.React Native相对于原生的ios和Android有哪些优势. react native一套代码可以开发出跨平台app, 减少了人力.节省了时间.避免了 iOS 与 Android 版本发 ...