【玩转 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. 详见本书第三章内容(自学笔记正在整理中) ↩︎

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

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

相关文章

java-(Oracle)-Oracle,plsqldev,Sql语法,Oracle函数

卸载好注册表,然后安装11g 每次在执行orderby的时候相当于是做了全排序,思考全排序的效率 会比较耗费系统的资源,因此选择在业务不太繁忙的时候进行 --给表添加注释 comment on table emp is 雇员表 --给列添加注释; comment on column emp.empno is 雇员工号;select empno,en…

尚硅谷课程【笔记】——大数据之Shell【一】

课程视频:【【尚硅谷】Shell脚本从入门到实战】 一、Shell概述 为什么要学习Shell? 1)需要看懂运维人员的Shell程序 2)偶尔编写一些简单的Shell程序来管理集群、提高开发效率 什么是Shell? 1)Shell是一…

pytorch实现长短期记忆网络 (LSTM)

人工智能例子汇总:AI常见的算法和例子-CSDN博客 LSTM 通过 记忆单元(cell) 和 三个门控机制(遗忘门、输入门、输出门)来控制信息流: 记忆单元(Cell State) 负责存储长期信息&…

CDDIS从2025年2月开始数据迁移

CDDIS 将从 2025 年 2 月开始将我们的网站从 cddis.nasa.gov 迁移到 earthdata.nasa.gov,并于 2025 年 6 月结束。 期间可能对GAMIT联网数据下载造成影响。

【Redis】主从模式,哨兵,集群

主从复制 单点问题: 在分布式系统中,如果某个服务器程序,只有一个节点(也就是一个物理服务器)来部署这个服务器程序的话,那么可能会出现以下问题: 1.可用性问题:如果这个机器挂了…

华为云kubernetes部署deepseek r1、ollama和open-webui(已踩过坑)

1 概述 ollama是一个管理大模型的一个中间层,通过它你可以下载并管理deepseek R1、llama3等大模型。 open-webui是一个web界面(界面设计受到chatgpt启发),可以集成ollama API、 OpenAI的 API。 用常见的web应用架构来类比&#x…

在Mac mini M4上部署DeepSeek R1本地大模型

在Mac mini M4上部署DeepSeek R1本地大模型 安装ollama 本地部署,我们可以通过Ollama来进行安装 Ollama 官方版:【点击前往】 Web UI 控制端【点击安装】 如何在MacOS上更换Ollama的模型位置 默认安装时,OLLAMA_MODELS 位置在"~/.o…

CSS 背景与边框:从基础到高级应用

CSS 背景与边框:从基础到高级应用 1. CSS 背景样式1.1 背景颜色示例代码:设置背景颜色 1.2 背景图像示例代码:设置背景图像 1.3 控制背景平铺行为示例代码:控制背景平铺 1.4 调整背景图像大小示例代码:调整背景图像大小…

数据思维错题知识点整理(复习)

小的知识点整理 目前常见的数据采集方案有什么。 埋点、可视化埋点、无埋点(无埋点并不是字面意思不埋点,其实也是一种埋点,只是让开发人员完全无感知,直接嵌入sdk,然后每个元素都能查看他们的情况,后续开…

PyQt4学习笔记2】QMainWindow

目录 一、创建 QMainWindow 组件 1. 创建工具栏 2. 创建停靠窗口 3. 设置状态栏 4. 设置中央窗口部件 二、QMainWindow 的主要方法 1. addToolBar() 2. addDockWidget() 3. setStatusBar() 4. setCentralWidget() 5. menuBar() 6. saveState() 和 restoreState() 三、QMainWind…

Linux:文件系统(软硬链接)

目录 inode ext2文件系统 Block Group 超级块(Super Block) GDT(Group Descriptor Table) 块位图(Block Bitmap) inode位图(Inode Bitmap) i节点表(inode Tabl…

ubuntu22.40安装及配置静态ip解决重启后配置失效

遇到这种错误,断网安装即可! 在Ubuntu中配置静态IP地址的步骤如下。根据你使用的Ubuntu版本(如 Netplan 或传统的 ifupdown),配置方法有所不同。以下是基于 Netplan 的配置方法(适用于Ubuntu 17.10及更高版…

手写MVVM框架-实现简单的数据代理

MVVM框架最显著的特点就是虚拟dom和响应式的数据、我们以Vue为例,分别实现data、computed、created、methods以及虚拟dom。 这一章我们先实现简单的响应式,修改数据之后在控制台打印。 我们将该框架命名为MiniVue。 首先我们需要创建MiniVue的类(src/co…

ESLint

ESLint ESLint 是一个针对 JS 的代码风格检查工具,当不满足其要求的风格时,会给予警告或错误。 官网:https://eslint.org/ 中文网:https://eslint.nodejs.cn/ 安装使用 在你的项目中安装 ESLint 包: npm install -…

kaggle视频行为分析1st and Future - Player Contact Detection

这次比赛的目标是检测美式橄榄球NFL比赛中球员经历的外部接触。您将使用视频和球员追踪数据来识别发生接触的时刻,以帮助提高球员的安全。两种接触,一种是人与人的,另一种是人与地面,不包括脚底和地面的,跟我之前做的这…

Chapter 6 -Fine-tuning for classification

Chapter 6 -Fine-tuning for classification 本章内容涵盖 引入不同的LLM微调方法准备用于文本分类的数据集修改预训练的 LLM 进行微调微调 LLM 以识别垃圾邮件评估微调LLM分类器的准确性使用微调的 LLM 对新数据进行分类 现在,我们将通过在大语言模型上对特定目标任…

【从零开始的LeetCode-算法】922. 按奇偶排序数组 II

给定一个非负整数数组 nums, nums 中一半整数是 奇数 ,一半整数是 偶数 。 对数组进行排序,以便当 nums[i] 为奇数时,i 也是 奇数 ;当 nums[i] 为偶数时, i 也是 偶数 。 你可以返回 任何满足上述条件的…

python 小游戏:扫雷

目录 1. 前言 2. 准备工作 3. 生成雷区 4. 鼠标点击扫雷 5. 胜利 or 失败 6. 游戏效果展示 7. 完整代码 1. 前言 本文使用 Pygame 实现的简化版扫雷游戏。 如上图所示,游戏包括基本的扫雷功能:生成雷区、左键点击扫雷、右键标记地雷、显示数字提示…

安全策略实验报告

1.实验拓扑图 2.实验需求 vlan2属于办公区,vlan3生产区 办公区pc在工作日时间可以正常访问OAserver,i其他时间不允许 办公区pc可以在任意时间访问Web server 生产区pc可以在任意时间访问OA server但不能访问web server 特例:生产区pc可以…

力扣73矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]] 输入:matrix [[0,1,2,0],[3,4,5,2],[…