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

book cover for the 2nd version

《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 对契约测试的相关背景做了一番了解,一并整理如下:

  1. 微服务架构的普及
  • 背景:随着微服务架构的广泛应用,系统被拆分为多个独立服务,服务间的通信变得复杂。
  • 挑战:服务接口的频繁变更容易导致集成问题,传统的集成测试难以应对这种快速变化。
  • 解决方案:契约测试通过定义服务间的接口契约,确保各服务在独立开发和部署时仍能正确交互。
  1. 持续交付与 DevOps 的推广
  • 背景:持续交付和 DevOps 要求快速、频繁地发布软件,同时保持高质量。
  • 挑战:传统测试方法耗时,难以满足快速发布的需求。
  • 解决方案:契约测试作为自动化测试的一部分,能在开发早期发现问题,提升发布效率。
  1. 分布式系统的复杂性增加
  • 背景:现代系统依赖大量第三方服务或云服务,增加了集成的复杂性。
  • 挑战:依赖服务的变更可能导致系统故障,传统测试难以覆盖所有场景。
  • 解决方案:契约测试通过模拟依赖服务的行为,确保系统在依赖变更时仍能正常工作。
  1. 工具和框架的成熟
  • 背景:随着 PactSpring Cloud Contract 等工具的发展,契约测试变得更加易用。
  • 影响:这些工具降低了实施契约测试的门槛,推动了其普及。
  1. 行业最佳实践的推广
  • 背景:越来越多的公司通过博客、会议分享契约测试的成功经验。
  • 影响:这些实践案例为其他团队提供了参考,进一步推动了契约测试的流行。
  1. 测试左移的趋势
  • 背景:测试左移强调在开发早期进行测试,以减少后期修复成本。
  • 挑战:传统测试方法难以在早期阶段有效实施。
  • 解决方案:契约测试在开发初期定义接口契约,帮助团队尽早发现集成问题。

总结

契约测试的流行是微服务架构、持续交付、分布式系统复杂性增加等多重因素共同作用的结果。随着工具和最佳实践的成熟,契约测试逐渐成为现代软件开发中不可或缺的一部分。

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 按钮导入该文件:

img13.1

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

img13.2

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

img13.3

img13.4

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

图 13.1 初始导入 budgeting.yaml 文件后看到的契约测试 API 实例

【图 13.1 初始导入 budgeting.yaml 文件后看到的契约测试 API 实例】

6 API 实例的基本用法

导入成功后,按照之前的配置,Postman 会根据 YAML 文件自动生成一个 Definition 定义层(用于存放导入的 YAML 文件),以及一个同名的测试集合层 Budgeting API

图 13.2 基于导入的 OpenAPI 规范文件,由 Postman 自动生成的 API 实例结构

【图 13.2 基于导入的 OpenAPI 规范文件,由 Postman 自动生成的 API 实例结构】

该 API 实例的最大特点在于:定义层的任何内容变更,通过相关的同步设置,都将与下方的集合层保持一致。此外,侧边栏 Collection 标签中也会生成一个同名的测试集合。经实测,该集合的主要作用是创建契约测试所必需的 Mock 服务器,但并非主要关注对象;本章所有的核心操作都在 API 标签中。

开启定义层与集合层的同步方法如下图所示:

图 13.3 定义层与集合层的变更同步配置启用方法

【图 13.3 定义层与集合层的变更同步配置启用方法】

DIY 实测:将定义层中的 /items 路径改为 /changedItems,观察集合层同步后的效果。

img13.8

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

img13.9

img13.10

同步后的最终结果如下:

图 13.4 通过自动同步新增的两个测试请求

【图 13.4 通过自动同步新增的两个测试请求】

实测发现,同步只是将请求的 URL 更新了,但没有像书中说的那样,将它们移动到 items 文件夹下;即使改回原值,同步后也无法回到 items 文件夹中,并且同步设置无法关联到 Collection 侧边栏中的同名集合。这只能说明 Postman 在同步功能上还有瑕疵,目前仅支持导入时自动创建子文件夹;同步时仅在 URL 实现了与 YAML 定义层的同步,想要达到书中所说的 完美还原,还得手动操作。

7 API 实例的类型实时检查

另一个真正强大的地方在于,定义层与集合层真正实现了类型检查的实时同步:

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

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

图 13.6 单击请求上方的告警图标,还可以看到具体的报错原因

【图 13.6 单击请求上方的告警图标,还可以看到具体的报错原因】

同理,如果调整定义层中的字段类型,集合层中受影响的所有请都会出现告警图标。例如将 item 中的 amount 属性从 integer 改为 number,集合层中的三个请求都将提示类型问题:

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

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

图 13.8 amount 改为 number 类型后,受影响的测试请求都将校验失败

【图 13.8 amount 改为 number 类型后,受影响的测试请求都将校验失败】

但是,像这样的类型双向同步检查虽然强大,却并不是本章想要的契约测试。本章后续将通过一个专门的契约测试生成工具,实现目标集合的无侵入测试。但也是因为没有完整介绍新增的这部分内容,导致后期实测时走了很多弯路。

(上篇完)


  1. 详见本书第三章内容(自学笔记正在整理中) ↩︎

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

The specified Gradle distribution ‘gradle-bin.zip‘ does not exist.

The specified Gradle distribution ‘https://services.gradle.org/distributions/gradle-bin.zip’ does not exist. distributionUrl不存在,关联不上,下载不了,那就匹配一个能下载的 distributionUrlhttps://services.gradle.org/distrib…

【Linux系统】线程:认识线程、线程与进程统一理解

一、更新认知 之前的认知 进程:一个执行起来的程序。进程 内核数据结构 代码和数据线程:执行流,执行粒度比进程要更细。是进程内部的一个执行分值 更新认识: a. 进程是承担分配系统资源的基本实体b. 线程是OS调度的基本单位 …

请求响应(接上篇)

请求 日期参数 需要在前面加上一个注解DateTimeFormat来接收传入的参数的值 Json参数 JSON参数:JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数,需要使用 RequestBody 标识 通过RequestBody将JSON格式的数据封装到实体类…

Linux提权--SUDO提权

​sudo​ 是 Linux 中常用的特权管理工具,允许普通用户以其他用户(通常是 root 用户)的身份运行命令。如果配置不当,攻击者可能通过滥用 sudo​ 权限来提升自己的权限。 一.常见的 sudo 提权方法: 误配置的 sudo 权限&…

【Elasticsearch】filter聚合

在Elasticsearch中,Filter聚合是一种单桶聚合,用于根据特定的查询条件筛选文档,并对筛选后的文档集合进行进一步的聚合分析。它允许用户在执行聚合操作之前,先过滤出符合某些条件的文档,从而更精确地分析数据。 Filter…

Colorful/七彩虹 隐星P15 TA 24 原厂Win11 家庭版系统 带F9 Colorful一键恢复功能

Colorful/七彩虹 隐星P15 TA 24 原厂Win11 家庭中文版系统 带F9 Colorful一键恢复功能 自动重建COLORFUL RECOVERY功能 带所有随机软件和机型专用驱动 支持机型:隐星P15 TA 24 文件下载:asusoem.cn/745.html 文件格式:ISO 系统版本&…

实时波形与频谱分析———傅立叶变换

实时波形与频谱分析:一个交互式动画演示 在信号处理领域,时域波形和频域频谱是理解信号特性的重要工具。通过时域波形,我们可以直观地观察信号随时间的变化,而频域频谱则揭示了信号中所包含的频率成分及其幅值。为了帮助大家更好…

03链表+栈+队列(D1_链表(D1_基础学习))

目录 一、什么是链表 二、基本操作 三、为什么要使用链表 四、为什么能够在常数时间访问数组元素 数组优点 数组缺点 五、动态数组诞生 链表优点 链表缺点 六、链表、数组和动态数组的对比 七、 链表种类 1. 单向链表 2. 双向链表 3. 循环链表 八、链表衍生 ...…

企业微信开发012_使用WxJava企业微信开发框架_封装第三方应用企业微信开发005_多企业授权实现---企业微信开发014

这里主要说一下如何授权的思路,如何来做,其实非常简单, 如果你有很多企业微信需要授权以后才能使用自己开发的,第三方企业微信功能,那么 首先,在企业列表中,你可以给某个企业去配置,这个企业,他对应的企业微信的,比如, 这个企业的企业id,cropID,当然还可以有,比如企业名称,用…

“AI智能分析综合管理系统:企业管理的智慧中枢

在如今这个快节奏的商业世界里,企业面临的挑战越来越多,数据像潮水一样涌来,管理工作变得愈发复杂。为了应对这些难题,AI智能分析综合管理系统闪亮登场,它就像是企业的智慧中枢,让管理变得轻松又高效。 过去…

蓝桥杯思维训练营(三)

文章目录 题目详解680.验证回文串 II30.魔塔游戏徒步旅行中的补给问题观光景点组合得分问题 题目详解 680.验证回文串 II 680.验证回文串 II 思路分析:这个题目的关键就是,按照正常来判断对应位置是否相等,如果不相等,那么就判…

[LeetCode] 二叉树 I — 深度优先遍历(前中后序遍历) | 广度优先遍历(层序遍历):递归法迭代法

二叉树 基础知识深度优先遍历递归法迭代法(栈)144# 二叉树的前序遍历94# 二叉树的中序遍历145# 二叉树的后序遍历 广度优先遍历递归法迭代法(队列)102# 二叉树的层序遍历107# 二叉树的层序遍历 II199# 二叉树的右视图637# 二叉树的…

Hugging Face GGUF 模型可视化

Hugging Face GGUF 模型可视化 1. Finding GGUF files (检索 GGUF 模型)2. Viewer for metadata & tensors info (可视化 GGUF 模型)References 无知小儿,仙家雄霸天下,依附强者才是唯一的出路。否则天地虽大,也让你们无路可走&#xff0…

基于Coze平台实现抖音链接提取文案转小红书文案的智能体开发全流程解析

文章目录 引言:跨平台内容运营的AI解法实例最终效果1. 平台特性对比与转化需求分析1.1 用户画像与内容风格对比1.2 文案转化核心需求2. Coze平台技术架构解析2.1 Coze核心能力矩阵2.2 关键技术组件选型3. 智能体工作流设计3.1 完整处理流程3.2 关键节点说明4. 核心模块实现详解…

【低功耗 Power 学习专栏 -- Power domian 和 power rail】

文章目录 power rail(followpin) 和 Power domain1. Power Domain2. Power Rail3. Followpin4. Power Stripe5. IR Drop芯片中电源管理设计 举例 power rail(followpin) 和 Power domain followpin 指两部分,一个就是 STD cell 上下的 VDD, VSS。同时,f…

PopupMenuButton组件的功能和用法

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了Sliver综合示例相关的内容,本章回中将介绍PopupMenuButton组件.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在本章回中介绍的PopupMenuButton组件位于AppBar右侧,…

TiDB 分布式数据库多业务资源隔离应用实践

导读 随着 TiDB 在各行业客户中的广泛应用 ,特别是在多个业务融合到一套 TiDB 集群中的场景,各企业对集群内多业务隔离的需求日益增加。与此同时,TiDB 在多业务融合场景下的资源隔离方案日趋完善,详情可参考文章 《你需要什么样的…

CommonAPI学习笔记-2

一. 概述 ​ 这篇文章主要是想整理并且分析CommonAPI代码生成工具根据fidl和fdepl配置文件生成出来的代码的结构和作用。 二. fidl ​ 用户根据业务需求在fidl文件中定义业务服务接口的结构以及自定义数据类型,然后使用core生成工具传入fidl文件生成该fidl的核心…

ELK模块封装starter

文章目录 1.combinations-elk-starter1.目录结构2.log4j2-spring.xml 从环境变量读取host和port3.ELKProperties.java 两个属性4.ELKAutoConfiguration.java 启用配置类5.ELKEnvironmentPreparedListener.java 监听器从application.yml中获取属性值6.spring.factories 注册监听…

KNN算法:从思想到实现(附代码)

引言 K最近邻算法(K Nearest Neighbors, KNN)是一种简单而有效的机器学习算法,用于分类和回归问题。其核心思想基于“近朱者赤,近墨者黑”,即通过测量不同特征值之间的距离来进行分类或预测数值。本文将详细介绍KNN的…