微服务契约测试框架Pact-Python实战

Pact是一个契约测试框架,有多种语言实现,本文以基于pact-python探究契约测试到底是什么?以及如何实现

官网:自述文件 |契约文档 (pact.io)

契约测试步骤

1、为消费者写一个单元测试,让它通过,并生成契约文件。

2、在生产者服务执行该契约文件,验证测试是否通过。

 安装pact-Python

官方介绍的是直接使用pip下载,但是国内下载有问题。

下载方法参考:契约测试第一步--pact-python安装_51CTO博客_pact 契约测试

下载安装包:

https://pypi.org/project/pact-python/0.19.0/#modal-close

 点击下载后手动解压:

入主目录,与setup.py同级,进入命令行执行:

python setup.py build      

python setup.py install

 消费者测试

新建项目,创建contract_miku.py文件

 代码

# -*- coding: utf-8 -*-
"""
@author dongfangbubai
@date 2023年07月27日 18:08:14
@packageName 
@className contract_miku
@describe 模拟消费者去请求真实的生产者
"""
import atexit
import unittest
# from query import get_cartoon_characters
import requestsfrom pact import Consumer,Provider
#构造pact对象,定义消费者服务的名字并给他绑定一个生产者服务
pact = Consumer('consumer').has_pact_with(Provider('provider'))
pact.start_service()#start mock service
# # #注册推出的时候关闭pact服务
atexit.register(pact.stop_service)class GetMikuInfoContract(unittest.TestCase):def test_miku(self):#定义期望的结果expected={"salary":20000,"name":"miku","national":"Chinese","contract":{"Email":"dongfangbubai@163.com","Phone":"13265523433"}}#定义expected响应头headers={"Content-Type":"application/json"}#定义预期请求以及响应的方式(consumer will request in this way and expected to get the repsponed from the procide)(pact.upon_receiving("a request for UserA")#请求的名字.with_request(method="GET",path='/information',query={"name":"miku"}) #期望的请求方法,请求url.will_respond_with(200,headers, expected)#期望请求的返回)#定义消费者服务向模拟生产者发生请求,并获得响应#the url and port is the mockservice not real provider with pact:#定义pactresult=requests.get('http://127.0.0.1:1234/information',{"name":"miku"})print(result)print(result.headers)print(result.json())#做最后的断言self.assertEqual(result.json(),expected)
if __name__ == '__main__':unittest.main()

可以看到首先构造一个pact,并使用pact启动mock服务。

在具体的测试类和方法中采用了unittest测试框架,采用什么测试框架可以根据所使用的语言,这里也可以用pytest。js语言就可以用mocha框架。

在test_miku函数中定义了expected,headers,在pact中定义消费者预期的请求方式和响应结果。后续会根据这些生成契约。

在with pact里定义向mock服务的请求,最后断言请求的结果与预期是否一致。

需要注意的是,with pact里的url是pact带的mock服务对应的1234端口,而不是真实的服务,也不能填写真实服务。

运行结果

使用python方式运行contract_miku.py

在窗口输出了一些关于ruby编码的提示,对结果好像没有影响。

在result.json的打印中可以看到打印的内容与我们的expected内容一致。

测试用例为通过状态。其实消费者端的单元测试代码无论expected怎么写,测试用例都是通过的,因为我们的目的就是写一个单元测试让测试用例通过。

契约文件

代码运行后,会生成consumer-provider.json文件,这就是契约文件。

契约文件里定义了consumer,provider的名称,和交互。

交互包括request,response,请求body。

契约文件就是消费者的需求,而生产者应该满足这些需求。

 生产者测试

这里采用flask框架生成了一个接口

api_server.py

# -*- coding: utf-8 -*-
"""
@author 
@date 2023年07月28日 09:31:25
@packageName 
@className api_server
@describe TODO
"""
import jsonfrom flask import Flask, request, jsonifyapp = Flask(__name__)rsp_body=[{"salary":20000,"name":"miku","national":"Chinese","contract":{"Email":"dongfangbubai@163.com","Phone":"13265523433"}}]
@app.route('/information')
def test():get_name=request.args.get("name","").lower()print(get_name)if get_name=='miku':rsp=jsonify(rsp_body[0])elif get_name=='nanpha':rsp = jsonify(rsp_body[1])else:rsp=jsonify({'status':'404 not found'})return rspif __name__ == '__main__':app.run(host='0.0.0.0',port=8080)

运行api_server.py,使用postman请求接口

 测试生产者服务只需要在命令行执行

pact-verifier --provider-base-url=http://localhost:8080 --pact-url=consumer-provider.json

 这里指定了生产者服务的url和契约文件即消费者测试生成的文件

运行结果显示没有失败,说明执行成功。

可以看到生产者服务返回的状态码,响应体和响应头都与契约文件匹配,所以验证成功。

契约测试与接口测试和集成测试的区别

 

 

 参考

【软件测试课程中——微服务架构测试中的契约测试。】 https://www.bilibili.com/video/BV1Qf4y1F76L/?p=4&share_source=copy_web&vd_source=1aab39b433529f6f488e61847b342350

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/14983.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OS-08-事件驱动:C10M是如何实现的?

08-事件驱动:C10M是如何实现的? 你好,我是陶辉。 上一讲介绍了广播与组播这种一对多通讯方式,从这一讲开始,我们回到主流的一对一通讯方式。 早些年我们谈到高并发,总是会提到C10K,这是指服务…

Kubernetes(K8s)从入门到精通系列之七:K8s的基本概念和术语之安全类

Kubernetes K8s从入门到精通系列之七:K8s的基本概念和术语之安全类 一、安全类二、Role和ClusterRole三、RoleBinding和ClusterRoleBinding一、安全类 开发的Pod应用需要通过API Server查询、创建及管理其他相关资源对象,所以这类用户才是K8s的关键用户。K8s设计了Service A…

MIT 6.830数据库系统 -- lab five

MIT 6.830数据库系统 -- lab five 项目拉取引言搜索练习1 BTreeFile.findLeafPage() 插入练习2 Spliting Page 删除练习3 页再分配练习4 合并页 事务小结 项目拉取 原项目使用ant进行项目构建,我已经更改为Maven构建,大家直接拉取我改好后的项目即可: …

centos安装mysql8

安装过程 基本安装过程同mysq5.7,参考:centos7安装mysql5.7_centos7 安装mysql5.7源_shuair的博客-CSDN博客 设置不区分大小写 切记,在第一次启动器前就应修改配置文件,设置不区分大小写,即初始化之前修改&#xff…

使用 docker 一键部署 MongoDB

目录 1. 前期准备 2. 导入镜像 3. 部署MongoDB脚本 4. 配置模板文件 5. 部署MongoDB 6. 部署后配置 7. 基本维护 1. 前期准备 新部署前可以从仓库(repository)下载 MongoDB 镜像,或者从已有部署中的镜像生成文件: # 查看…

Zookeeper入门介绍

Zookeeper在我本次系统的学习之前是已经开始使用了,但是并不理解Zookeeper到底是什么,有什么作用,你或许跟我有一样的疑惑,本专栏将会解决这些疑惑。 目录 Zookeeper介绍: zookeeper特点: 数据结构&#x…

NUMA架构在kubernetes中的应用

numactl使用 numactl 通过将 CPU 划分多个 node 减少 CPU 对总线资源的竞争,一般使用在高配置服务器部署多个 CPU 消耗性服务使用。 numactl使用,numa常用命令,numa命令行使用 #numactl -H available: 2 nodes (0-1) node 0 cpus: 0 2 4 6 8 10 12 14 16 18 20 22 node 0…

09mysql之数据处理之增删改

#1. 创建数据库dbtest11 CREATE DATABASE IF NOT EXISTS dbtest11 CHARACTER SET utf8; #2. 运行以下脚本创建表my_employees USE dbtest11; CREATE TABLE my_employees( id INT(10), first_name VARCHAR(10), last_name VARCHAR(10), userid VARCHAR(10), salary DOUBLE(10,2)…

《MySQL 实战 45 讲》课程学习笔记(二)

日志系统:一条 SQL 更新语句是如何执行的? 与查询流程不一样的是,更新流程还涉及两个重要的日志模块:redo log(重做日志)和 binlog(归档日志)。 重要的日志模块:redo l…

【VSCode部署模型】导出TensorFlow2.X训练好的模型信息

参考tensorflow2.0 C加载python训练保存的pb模型 经过模型训练及保存,我们得到“OptimalModelDataSet2”文件夹,模型的保存方法(.h5或.pb文件),参考【Visual Studio Code】c/c部署tensorflow训练的模型 其中“OptimalModelDataSet2”文件夹保…

Doris安装部署入门

文章目录 一 Doris 介绍1.1 使用场景1.1.2 Doris架构 二 Doris单机部署2.1 下载 Doris2.2 配置 Doris2.2.1 配置 FE2.2.2 启动 FE2.2.3 查看 FE 运行状态2.2.4 连接 FE2.2.5 停止 FE 节点2.2.6 配置 BE2.2.7 启动 BE2.2.8 添加 BE 节点到集群2.2.9 查看 BE 运行状态2.2.10 停止…

GitHub仓库如何使用

核心:GitHub仓库如何使用 目录 1.创建仓库: 2.克隆仓库到本地: 3.添加、提交和推送更改: 4.分支管理: 5.拉取请求(Pull Requests): 6.合并代码: 7.其他功能&…

网络知识整理

网络知识整理 网络拓扑网关默认网关 数据传输拓扑结构层面协议层面 网络拓扑 网关 连接两个不同的网络的设备都可以叫网关设备,网关的作用就是实现两个网络之间进行通讯与控制。 网关设备可以是交换机(三层及以上才能跨网络) 、路由器、启用了路由协议的服务器、代…

k8s Webhook 使用java springboot实现webhook 学习总结

k8s Webhook 使用java springboot实现webhook 学习总结 大纲 基础概念准入控制器(Admission Controllers)ValidatingWebhookConfiguration 与 MutatingWebhookConfiguration准入检查(AdmissionReview)使用Springboot实现k8s-Web…

Shell脚本学习2

文章目录 Shell脚本学习2运算符算术运算符关系运算符布尔运算符字符串运算符文件测试运算符 字符串拼接字符串获取字符串长度截取字符串查找字符串 数组条件控制if语句case语句for循环while循环until循环跳出循环 Shell脚本学习2 运算符 Bash 支持很多运算符,包括…

Linux 学习记录57(ARM篇)

Linux 学习记录57(ARM篇) 本文目录 Linux 学习记录57(ARM篇)一、外部中断1. 概念2. 流程图框 二、相关寄存器1. GIC CPU Interface (GICC)2. GIC distributor (GICD)3. EXTI registers 三、EXTI 寄存器1. 概述2. 内部框图3. 寄存器功能描述4. EXTI选择框图5. EXTI_EXTICR1 &…

vue3 +element动态表单实现

可以直接复制&#xff0c;接口看后端 父页面 <schedulesref"schedulesRef":dxbz"props.dxbz":jdlx"props.jdlx":woId"myWoId":addendumList"formInline.addendumList"v-if"addendumShow"addendum"addendu…

如何快速同步第三方平台数据?

全量的数据主要是针对多个系统的历史数据,大概有几千万数据,只需要初始化一次即可。 而增量的数据,是系统后续变更的数据。 这个需求其实不简单,至少有以下难点: 不能直接访问第三方数据库。 不能将历史数据导出到excel中,有泄露数据的风险。 如何快速同步历史数据? 增…

HTML <progress> 标签

实例 正在进行的下载&#xff1a; <progress value"22" max"100"></progress> 浏览器支持 元素ChromeIEFirefoxSafariOpera<progress>8.010.016.06.011.0 定义和用法 <progress> 标签标示任务的进度&#xff08;进程&#xf…

【kubernetes系列】flannel之vxlan模式原理

概述 在Kubernetes中要保证容器之间网络互通&#xff0c;网络至关重要。而Kubernetes本身并没有自己实现容器网络&#xff0c;而是而是借助CNI标准&#xff0c;通过插件化的方式自由接入进来。在容器网络接入进来需要满足如下基本原则&#xff1a; Pod无论运行在任何节点都可…