【玩转 Postman 接口测试与开发2_016】第13章:在 Postman 中实现契约测试(Contract Testing)与 API 接口验证(上)

《API Testing and Development with Postman》最新第二版封面
文章目录
- 第十三章 契约测试与 API 接口验证
- 1 契约测试的概念
- 2 契约测试的工作原理
- 3 契约测试的分类
- 4 DeepSeek 给出的契约测试相关背景
- 5 契约测试在 Postman 中的创建方法
- 6 API 实例的基本用法
- 7 API 实例的类型实时检查
写在前面
由于微服务和 DevOps 持续集成工作流的需要,API 契约测试逐渐受到人们的关注。本章也是第二版全新升级的内容,创新引入了一个开源项目实现了对目标集合的无侵入式契约测试。但也是因为这部分内容介绍得很不完整,导致我在实际练手时走了很多弯路。特此梳理出来,方便后续复盘。由于篇幅较长,特分为上下两篇进行梳理。本篇为上篇,介绍契约测试的基本概念和在 Postman 中的创建方法。下篇重点演示契约测试生成工具的详细用法,敬请关注。
第十三章 契约测试与 API 接口验证
本章概要
- 理解契约测试相关概念
- 契约测试在
Postman中的设置方法- 契约测试的执行与维护
1 契约测试的概念
定义:契约测试是确保两个不同的软件服务实现相互通信的一种方式。
API 接口其实就是一份契约:它规定了客户端调用后台服务时必须遵守的一套规则。
契约测试就是对该契约进行检查,确保不出岔子。
2 契约测试的工作原理
契约测试的意义在于,允许人们只验证契约本身是否正确,而无需包含完整的 API 调用。最好是让该契约通过像 OpenAPI 这样的规范完整记录下来 1。
从本质上讲,Mock 服务器也是一个契约,可供前端或 API 消费端使用;但其缺陷也很明显:后端无法调用该契约。如果模拟服务器与真实的后端接口不一致,只能逐一排查 Mock 中的各个示例,既耗时又低效。
理想中的契约测试应该是接口供应方也能运行测试的一套 API 接口,可以验证其变更不影响、不破坏消费方的正常使用。例如,对比一个普通的端点测试:
pm.test("Check the name", function () {const jsonData = pm.response.json();pm.expect(jsonData.name).to.eql("Bob");
});
上述代码换作契约测试,则更侧重于是否获取了正确的数据类型(字符串),以及 name 字段是否为响应对象的一级属性。
3 契约测试的分类
按照由哪一方制定契约,契约测试可分为两大类:
- Consumer-driven contracts:消费者驱动契约(CDC),由 API 消费者定义契约,明确其需求;
- 优点:
- 确保 API 提供对消费者有价值的功能;
- 有助于了解消费者的使用习惯,避免破坏现有工作流。
- 缺点:
- 多个消费者的契约测试可能导致冗余和低效;
- 消费者的特殊需求或将限制 API 的升级改造。
- 优点:
- Provider-driven contracts:提供者驱动契约(PDC),由 API 提供者定义契约,具有明确支持的数据格式和行为;
- 优点:
- 提供者可以明确限定接口用法,避免对未定义行为的依赖;
- 扩展性更好,适用于存在大量用户的场景。
- 缺点:
- 缺乏消费者反馈,难以察觉用户的特有用法和操作习惯;
- 可能更容易破坏用户所依赖的功能。
- 优点:
知识拓展
本节还提到了著名的 海勒姆定律(Hyrum’s Law):
With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody.
如果一个 API 接口的用户足够多,那么在契约中承诺什么并不重要,因为系统可观测到的一切行为都将被某一部分用户所依赖。—— Hyrum’s Law
这就意味着:无论契约如何定义,用户总会以预料之外的方式使用 API,契约测试有助于减少破坏性变更。
4 DeepSeek 给出的契约测试相关背景
由于本章对契约测试的介绍还是过于基础,我又结合 DeepSeek 对契约测试的相关背景做了一番了解,一并整理如下:
- 微服务架构的普及
- 背景:随着微服务架构的广泛应用,系统被拆分为多个独立服务,服务间的通信变得复杂。
- 挑战:服务接口的频繁变更容易导致集成问题,传统的集成测试难以应对这种快速变化。
- 解决方案:契约测试通过定义服务间的接口契约,确保各服务在独立开发和部署时仍能正确交互。
- 持续交付与 DevOps 的推广
- 背景:持续交付和
DevOps要求快速、频繁地发布软件,同时保持高质量。- 挑战:传统测试方法耗时,难以满足快速发布的需求。
- 解决方案:契约测试作为自动化测试的一部分,能在开发早期发现问题,提升发布效率。
- 分布式系统的复杂性增加
- 背景:现代系统依赖大量第三方服务或云服务,增加了集成的复杂性。
- 挑战:依赖服务的变更可能导致系统故障,传统测试难以覆盖所有场景。
- 解决方案:契约测试通过模拟依赖服务的行为,确保系统在依赖变更时仍能正常工作。
- 工具和框架的成熟
- 背景:随着
Pact、Spring Cloud Contract等工具的发展,契约测试变得更加易用。- 影响:这些工具降低了实施契约测试的门槛,推动了其普及。
- 行业最佳实践的推广
- 背景:越来越多的公司通过博客、会议分享契约测试的成功经验。
- 影响:这些实践案例为其他团队提供了参考,进一步推动了契约测试的流行。
- 测试左移的趋势
- 背景:测试左移强调在开发早期进行测试,以减少后期修复成本。
- 挑战:传统测试方法难以在早期阶段有效实施。
- 解决方案:契约测试在开发初期定义接口契约,帮助团队尽早发现集成问题。
总结
契约测试的流行是微服务架构、持续交付、分布式系统复杂性增加等多重因素共同作用的结果。随着工具和最佳实践的成熟,契约测试逐渐成为现代软件开发中不可或缺的一部分。
5 契约测试在 Postman 中的创建方法
接下来就开始了本章的填坑之旅——看似很丝滑的操作实测后才发现每一步都很艰难,因为作者漏掉了很多关键细节……
作者沿用了第 3 章制定的基于 OpenAPI 规范的预算管理 API 接口文件(即 budgeting.yaml,详见:https://github.com/PacktPublishing/API-Testing-and-Development-with-Postman-Second-Edition/blob/main/Chapter13/budgeting.yaml)。
先通过 Postman 左上角的 Import 按钮导入该文件:

接着在弹出的窗口中拖入 budgeting.yaml 文件或点击上传:

在弹出的新页面中确认选中 OpenAPI 这项,并且在下方的导入配置中,必须确认参数生成模式是按 Schema 生成的:


这样就会在 Postman 的 API 侧边栏看到用于演示本章契约测试的 API 实例:

【图 13.1 初始导入 budgeting.yaml 文件后看到的契约测试 API 实例】
6 API 实例的基本用法
导入成功后,按照之前的配置,Postman 会根据 YAML 文件自动生成一个 Definition 定义层(用于存放导入的 YAML 文件),以及一个同名的测试集合层 Budgeting API:

【图 13.2 基于导入的 OpenAPI 规范文件,由 Postman 自动生成的 API 实例结构】
该 API 实例的最大特点在于:定义层的任何内容变更,通过相关的同步设置,都将与下方的集合层保持一致。此外,侧边栏 Collection 标签中也会生成一个同名的测试集合。经实测,该集合的主要作用是创建契约测试所必需的 Mock 服务器,但并非主要关注对象;本章所有的核心操作都在 API 标签中。
开启定义层与集合层的同步方法如下图所示:

【图 13.3 定义层与集合层的变更同步配置启用方法】
DIY 实测:将定义层中的 /items 路径改为 /changedItems,观察集合层同步后的效果。

单击集合层,并在右边详情页单击该同步图标,会看到一个确认变更情况的中间页面:


同步后的最终结果如下:

【图 13.4 通过自动同步新增的两个测试请求】
实测发现,同步只是将请求的 URL 更新了,但没有像书中说的那样,将它们移动到 items 文件夹下;即使改回原值,同步后也无法回到 items 文件夹中,并且同步设置无法关联到 Collection 侧边栏中的同名集合。这只能说明 Postman 在同步功能上还有瑕疵,目前仅支持导入时自动创建子文件夹;同步时仅在 URL 实现了与 YAML 定义层的同步,想要达到书中所说的 完美还原,还得手动操作。
7 API 实例的类型实时检查
另一个真正强大的地方在于,定义层与集合层真正实现了类型检查的实时同步:

【图 13.5 任意变更示例中的属性值类型,Postman 会自动实时出现告警提示】

【图 13.6 单击请求上方的告警图标,还可以看到具体的报错原因】
同理,如果调整定义层中的字段类型,集合层中受影响的所有请都会出现告警图标。例如将 item 中的 amount 属性从 integer 改为 number,集合层中的三个请求都将提示类型问题:

【图 13.7 将定义层从的 amount 类型改为 number 并保存】

【图 13.8 amount 改为 number 类型后,受影响的测试请求都将校验失败】
但是,像这样的类型双向同步检查虽然强大,却并不是本章想要的契约测试。本章后续将通过一个专门的契约测试生成工具,实现目标集合的无侵入测试。但也是因为没有完整介绍新增的这部分内容,导致后期实测时走了很多弯路。
(上篇完)
详见本书第三章内容(自学笔记正在整理中) ↩︎
相关文章:
【玩转 Postman 接口测试与开发2_016】第13章:在 Postman 中实现契约测试(Contract Testing)与 API 接口验证(上)
《API Testing and Development with Postman》最新第二版封面 文章目录 第十三章 契约测试与 API 接口验证1 契约测试的概念2 契约测试的工作原理3 契约测试的分类4 DeepSeek 给出的契约测试相关背景5 契约测试在 Postman 中的创建方法6 API 实例的基本用法7 API 实例的类型实…...
25.02.04 《CLR via C#》 笔记14
第二十一章 托管堆和垃圾回收 内存分配过程 CLR维护一个“下一次分配指针”(NextObjPtr),指向当前托管堆中第一个可用的内存地址 计算类型所需的字节数,加上对象开销(类型对象指针、同步块索引)所需字节数…...
day8-面向对象
目录 面向对象1、面向对象介绍2、类和对象类和对象类的几个补充注意事项 3、封装 面向对象 1、面向对象介绍 ⭐️面向对象介绍: 面向:拿、找对象:能干活的东西面向对象编程:拿东西过来做对应的事情 面向对象编程的例子&#x…...
Pyside6 的QObject 类
PySide6 中的 QObject 是 Qt 框架的核心基类,所有需要信号与槽、事件处理、内存管理的对象均需要继承自它。以下是关于 QObject 的详细说明,从功能、关键特性到实际代码示例进行阐述: 1. 核心功能 QObject 提供了以下基本能力: …...
【Java】位图 布隆过滤器
位图 初识位图 位图, 实际上就是将二进制位作为哈希表的一个个哈希桶的数据结构, 由于二进制位只能表示 0 和 1, 因此通常用于表示数据是否存在. 如下图所示, 这个位图就用于标识 0 ~ 14 中有什么数字存在 可以看到, 我们这里相当于是把下标作为了 key-value 的一员. 但是这…...
基于联合概率密度与深度优化的反潜航空深弹命中概率模型研究摘要
前言:项目题材来自数学建模2024年的D题,文章内容为笔者和队友原创,提供一个思路。 摘要 随着现代军事技术的发展,深水炸弹在特定场景下的反潜作战效能日益凸显,如何最大化的发挥深弹威力也成为重要研究课题。本文针对评估深弹投掷落点对命中潜艇概率的影响进行分析,综合利…...
【自然语言处理(NLP)】生成词向量:GloVe(Global Vectors for Word Representation)原理及应用
文章目录 介绍GloVe 介绍核心思想共现矩阵1. 共现矩阵的定义2. 共现概率矩阵的定义3. 共现概率矩阵的意义4. 共现概率矩阵的构建步骤5. 共现概率矩阵的应用6. 示例7. 优缺点优点缺点 **总结** 目标函数训练过程使用预训练的GloVe词向量 优点应用总结 个人主页:道友老…...
红黑树的封装
一、封装思路 在 STL 中 map set 的底层就是封装了一棵红黑树。 其中连接红黑树和容器的是迭代器,map set 暴露出的接口都不是自己写的,而是红黑树写的,外部接口封装红黑树接口。 所以写出红黑树为 map set 写的接口,再在上层的…...
巧用 Cursor+Coze,轻松简化小程序开发
一、为啥要用 Cursor+Coze 简化小程序开发 家人们,如今小程序简直火出圈啦!不管你是电商从业者,还是服务行业的工作者,又或是自媒体运营者,拥有一个小程序,就相当于给业务插上了腾飞的翅膀,能带来更多的流量和机会。但是,小程序开发的过程,那可真是充满了挑战。从最开…...
如何获取sql数据中时间的月份、年份(类型为date)
可用自带的函数month来实现 如: 创建表及插入数据: create table test (id int,begindate datetime) insert into test values (1,2015-01-01) insert into test values (2,2015-02-01) 执行sql语句,获取月份: select MONTH(begindate)…...
NSSCTF Pwn [NISACTF 2022]ezpie 题解
下载 exeinfo checksec 32位 NX PIE开启 查看main函数: 后门函数: 发现已经给出了main函数地址 因为开启了PIE 所以IDA中 后门函数减去main函数的后三位就是偏移 给出的函数加上这个数就是后门函数地址 exp: from pwn import *p remote(…...
数据结构与算法——二分查找
二分查找算法常用于在具有单调性的数组中,以logn的时间复杂度快速查找某个目标值是否存在于该数组中,如果存在还能够返回目标值在数组中的索引下标,常见的二分查找算法有开区间写法、半开区间写法以及闭区间写法,这三种写法的区别…...
【01】共识机制
BTF共识 拜占庭将军问题 拜占庭将军问题是一个共识问题 起源 Leslie Lamport在论文《The Byzantine Generals Problem》提出拜占庭将军问题。 核心描述 军中可能有叛徒,却要保证进攻一致,由此引申到计算领域,发展成了一种容错理论。随着…...
文字加持:让 OpenCV 轻松在图像中插上文字
前言 在很多图像处理任务中,我们不仅需要提取图像信息,还希望在图像上加上一些文字,或是标注,或是动态展示。正如在一幅画上添加一个标语,或者在一个视频上加上动态字幕,cv2.putText 就是这个“文字魔术师”,它能让我们的图像从“沉默寡言”变得生动有趣。 今天,我们…...
【R语言】环境空间
一、环境空间的特点 环境空间是一种特殊类型的变量,它可以像其它变量一样被分配和操作,还可以以参数的形式传递给函数。 R语言中环境空间具有如下3个特点: 1、对象名称唯一性 此特点指的是在不同的环境空间中可以有同名的变量出现&#x…...
惰性函数【Ⅱ】《事件绑定的自我修养:从青铜到王者的进化之路》
【Ⅱ】《事件绑定的自我修养:从青铜到王者的进化之路》 1. 代码功能大白话(给室友讲明白版) // 青铜写法:每次都要问浏览器"你行不行?" function addEvent青铜版(element, type, handler) {if (window.add…...
Vue3的el-table-column下拉输入实时查询API数据选择的实现方法
由于本人对el-table-column有下拉输入选择的要求,根据网上搜索的资料及本人优化,推出我比较满意的方法,供各位读者参考使用。 效果图 el-table-column写法 <el-table-columnlabel"货品编号"align"center"prop"…...
[mmdetection]fast-rcnn模型训练自己的数据集的详细教程
本篇博客是由本人亲自调试成功后的学习笔记。使用了mmdetection项目包进行fast-rcnn模型的训练,数据集是自制图像数据。废话不多说,下面进入训练步骤教程。 注:本人使用linux服务器进行展示,Windows环境大差不差。另外࿰…...
#systemverilog# Verilog与SystemVerilog发展历程及关系
1. Verilog的发展历史 1984年:Gateway Design Automation公司开发了Verilog,最初作为专有语言,用于逻辑仿真和数字电路设计。 1990年:Cadence收购Gateway,Verilog逐步开放,成为行业标准。 1995年(IEEE 1364-1995):首个IEEE标准,即Verilog-1995,定义基础语法和仿真语…...
RFID涉密载体管控系统|支持国产化、自主研发
涉密载体管理系统DW-S402是一套成熟系统,是用于对各种涉密载体进行有效管理,实现对载体的智能化、规范化、标准化管理,广泛应用于保密、机要单位以及企事业单位等有载体保管需求的行业。 用户为对文件资料、存储介质等管理严格的单位&#x…...
BUU14 [极客大挑战 2019]PHP1
用dirsearch扫描文件,扫了一万年什么也没扫出来 从网上看的wp,他们扫出来www.zip 这里直接用上了,以后有空再扫一遍 下载www.zip 在index.php中 说明要输入select 打开class.php <?php include flag.php;error_reporting(0);class…...
数据分析师使用Kutools for Excel 插件
数据分析师使用Kutools for Excel 插件 Kutools for Excel 是一款功能强大的 Excel 插件,旨在提高 Excel 用户的工作效率,简化复杂的操作。它提供了超过 300 个增强功能,帮助用户快速完成数据管理、格式化、排序、分析等任务,特别…...
【高级篇 / IPv6】(7.2) ❀ 04. 在60E上配置ADSL拨号宽带上网(IPv4) ❀ FortiGate 防火墙
【简介】除了单位用户以外,大部分个人用户目前使用的仍然是30E、50E、60E系列防火墙,固件无法达到目前最高版本7.6,这里以最常用的60E为例,演示固件版本7.2下实现ADSL拨号宽带的IPv6上网。由于内容比较多,文章分上、下…...
基于LMS算法的自适应滤波器设计与MATLAB实现
1. 引言 自适应滤波器是信号处理领域的重要工具,能够根据输入信号的统计特性自动调整滤波器参数。其中,最小均方(LMS)算法因其计算简单、易于实现的特点,成为最常用的自适应滤波算法之一,广泛应用于噪声消…...
【现代深度学习技术】深度学习计算 | 延后初始化自定义层
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重…...
LeetCode 3105. Longest Strictly Increasing or Strictly Decreasing Subarray
🔗 https://leetcode.com/problems/longest-strictly-increasing-or-strictly-decreasing-subarray 题目 给一个数组,返回其最长严格升序或者降序的子数组长度 思路 模拟 代码 class Solution { public:int longestMonotonicSubarray(vector<in…...
Java导出Excel简单工具类
一、maven配置 <!--jxl--><dependency><groupId>net.sourceforge.jexcelapi</groupId><artifactId>jxl</artifactId><version>2.6.12</version></dependency>二、工具类方法 package util2;import jxl.Workbook; impor…...
蓝桥与力扣刷题(141 环形链表)
题目:给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的…...
【小鱼闪闪】做一个物联网控制小灯的制作流程简要介绍(图文)
1、注册物联网云平台,这里选用巴法云 2.、新建主题 “ledtest” 3、 使用Arduino或Mixly软件编写单片机程序(需要引用巴法云库文件),程序中订阅“ledtest”主题,用于接收单片机发送来的数据。此处会将连接的温度传感器…...
图论常见算法
图论常见算法 算法prim算法Dijkstra算法 用途最小生成树(MST):最短路径:拓扑排序:关键路径: 算法用途适用条件时间复杂度Kruskal最小生成树无向图(稀疏图)O(E log E)Prim最小生成树无…...
