系统的可靠性等于各个依赖服务的可靠性的乘积 也就是说:A服务的可靠性是99%,B服务的可靠性是99%,C服务 的可靠性是99%,如果⼀一个系统需要A调⽤用B,B调⽤用C,那么这个 系统的可靠性=0.99*0.99*0.99=0.9702 契约是规定得到多 ⽅方承认、信守的内容 契约测试是验证服务的Provider是否按照期望的⽅方式与服 务的Consumer进⾏行行交互,简单的说是Consumer与Provider两者之间的集成。 契约测试是以消费者提出接⼝口契约,交由服务提供⽅方实现,并以测试⽤用例例对 契约进⾏行行产⽣生约束,所以服务提供⽅方在满⾜足测试⽤用例例的情况下可以⾃自⾏行行更更改 接⼝口或架构实现⽽而不不影响消费者。 契约测试是⼀一种针对外部服务的接⼝口进⾏行行的测试,它能够验证服务是否满⾜足 消费⽅方期待的契约。 它的本质是从利利益相关者的⽬目标和动机出发,最⼤大限 度地满⾜足需求⽅方的业务价值实现。
契约测试 契约测试(contract test)第一次出现在Martin Fowler的一篇文章中。 生产者-消费者(provider- comsumer)模式促生了契约测试,契约测试应该称为消费者驱动的契约测试(Cunsumer-Driven Contract Testing,CDCT)。 契约测试从消费者的角度定义测试,通过给API提供方提供契约,实现功能。 契约测试的核心原则是由消费者提出接口契约,由服务提供方实现,并用测试用例对契约进行约束,所以服务提供方在满足测试用例的情况下可以自行更改接口或架构实现而不影响消费者。 在执行生产者的测试时,无须重新完成生产者的测试用例,只需要以Pact记录下来的消费者契约作为测试的输入,完成与生产者的交互,来验证生产者是否满足消费者契约。
为了解决这类的问题,契约测试应运而生。契约测试不是一个新鲜东西,但在实际项目经历中发现用好契约测试真的会大大增强开发的效率,因此写下这篇文章来简单总结一下契约测试的一些内容。 首先什么是契约测试 契约测试是一个为确保两个独立的系统或者微服务能够兼容并可以相互通信的一个方法,契约测试分为两种,一种是服务提供者驱动的,另一种是消费者驱动的。 契约测试主要是为了验证服务层提供的数据是否能够消费者正常使用,它不会深入去测试服务的行为,而只是专注于测试服务的输入与输出,因此相比于沉重的集成测试而言,契约测试会更加的轻巧,快速。 契约测试形式上类似于API级别的UT,但其本质上还是个集成测试,比API测试在金字塔的位置更靠顶端,所以容易导致契约测试的数量增加和不稳定性增加。 契约测试具体是如何实践的 接下来我们分别从代码和流水线设计两方面来阐述一下具体的契约测试的实践: 代码层面: 为了完成契约测试,我们可以借助一个叫pact的工具。
“ 消费者驱动契约测试对于API或微服务开发非常重要,它解耦了API提供者和消费者间的开发与测试过程。” API或微服务间的集成测试不容易,且成本高昂。 当测试出现问题,修复的周期也长。 基于以上痛点,契约测试应运而生,它解耦了API提供者和消费者间的开发与测试过程。 双方只需要约定对API接口的期望(假设提供者收到怎样的请求会产生怎样的响应)并通过一份“契约”把它固化下来。彼此就可以分别围绕着这份契约按照自己的开发步伐进行独立的接口测试。 ? Spring Cloud提供了Spring Cloud Contract框架来支持契约测试。 其大致过程为: API消费者与提供者约定契约; Spring Cloud Contract的Maven/Gradle Plugin会自动根据契约生成JUnit的测试程序,供API提供者来测试其行为是否满足契约的预期
解决方案 解决方式首先是依赖关系的解耦,去掉直接对外部API的依赖,而是内部和外部系统都依赖于一个双方共同认可的约定—“契约”,并且约定内容的变化会被及时感知;其次,将系统之间的集成测试,转换为由契约生成的单元测试 ,例如通过契约描述的内容,构建测试替身。 这样,同时契约替代外部API成为信息变更的载体 契约测试也叫消费者驱动测试。 “契约”去实现。 我们可以通过SCHEMA来实现接口的契约测试。 API测试:通过FAKER生成测试数据,通过SCHEMA检查返回结果 ? image 需求 假定有如主图相同的http请求。
这样,依赖契约的测试效率优于集成测试,同时契约替代外部API成为信息变更的载体。 ? 2.测试效率对比(横向) 环境依赖: 单元测试:程序集 契约测试:程序集、依赖契约文件、虚拟路由服务 端到端测试:程序集、真实路由服务、前端UI 运行速度: 单元测试 > 契约测试 > 端到端测试 Pact 同时也说明契约测试存在一些不适用的场景,要依据使用场景区别对待。契约测试没有取代单元测试以及E2E测试。 ---- 契约测试与CD的整合 ? 目前解决方案是,人为制造一个“瓶颈”,保证同时只有一个契约测试在运行,保存的只有一个版本。 2.契约测试可维护性如何? 构建契约测试类似于单元测试,并且在Pact的框架下十分方便维护。 但是,测试框架本身还有一些问题,诸如,大小写敏感,空值验证,只有一份契约文件,契约测试分组等。
在“依赖项”对话框中搜索并添加“web”依赖项,为了后面的契约文件,再加入“Config Client ”和“Contract Stub Runner依赖项。 > <artifactId>com.example</artifactId> <version>1.0.0-SNAPSHOT</version> <properties> <java.version>11 123456" 并且储户借记卡账户余额为"100.00"元 当储户将卡插入ATM 并且储户选择查询余额 那么提示储户输入密码 并且输入密码"654321" 那么储户可以看到密码错误的提示 5 先来看看测试文件 HttpStatus.BAD_REQUEST); return response; } } 在卡片项目中运行 mvn spring-boot:run 启动卡片项目 然后运行amt下的mvn test测试通过 11 我的问题,如何测试在浏览器中输入http://127.0.0.1:8080/verify_pin/1111222233/123456显示pass信息,123456为其他字符显示fail信息。
在契约测试的帮助下,很多团队真正提升了开发效率,掌握了自己的节奏,但也有些团队发现效果并不明显,因为契约测试带来的收益并不是免费的。 契约测试有着不少的开发成本,每有一个新的需求,新的接口,新的字段,或是老字段的可空性发生了改变,以及枚举值的增加或减少,都需要增加或减少一些测试用例,然后在测试的过程中生成新的契约。 消费方回去写自己的契约测试,生成契约 (通常以 OpenApi doc 形式),然后以契约测试驱动,开发自己的逻辑 服务方拿到生成的契约,进行测试驱动开发,验证契约是否被满足 契约测试有时修改代价高 在使用契约测试时经常有这样的感受:比如,一些简单的契约,比如非空字段和格式校验等,每种情况都要专门的测试用例,而实现它却只需要一个注解,有点得不偿失。 更重要的是,随着测试的编写,生成的契约可能比当时商讨的更为简单,比如一些 400, 401 等情况,有时并不会为每一个 API 写足够细节足够详尽的测试;也可能生成的契约比商讨的更为详细,比如消费方在编写契约测试的过程中考虑到了更多的边缘场景
接口一改,前端就崩——契约测试能提前抓"接口行为偏离约定"。WorkBuddy 可以基于接口定义(OpenAPI/手写说明)生成契约测试脚本,验证"实际响应是否符合约定"。 本文给一套契约测试生成提示词工作流。一、为什么需要契约测试单元测试管内部逻辑,契约测试管"对外承诺"。AI 把接口文档转成可运行的断言脚本,接口被改坏时立刻红。 二、核心提示词模板(可直接复制)请基于下面的 API 定义生成契约测试脚本。 五、进阶:接入 CI追加"把这套契约测试写成可在 CI 跑的最小配置说明(如 GitHub Actions 步骤),每次 PR 自动验接口",把一次性脚本变持续护栏。 坑三:契约脚本依赖真实环境状态——应 mock 或固定测试数据。七、小结契约测试把"接口约定"变成"可执行的护栏"。本文模板让 AI 从定义直接产出断言,是前后端协作最稳的质量网。
契约测试分别验证双方是否履约——消费者测试验证能否处理预期响应,提供者测试验证是否真正输出消费者期望的内容。任何一方违约,测试都会在上线前失败。 Pact 框架实战指南 Pact 是目前最流行的契约测试框架,特别适合 Java 微服务生态。它分为消费者测试和提供者测试两部分。 通过将契约测试集成到 CI/CD 流水线,团队可以在每次变更时自动校验接口兼容性,极大降低跨团队协作风险。 消费者测试定义期望并生成 JSON 契约文件,提供者测试使用契约验证真实服务。 契约测试最佳实践 契约测试为微服务架构带来更高的独立性和安全性。以下是落地契约测试的最佳实践建议: • 从关键接口入手:优先为核心业务和高风险接口实施契约测试,逐步扩展覆盖范围。 • 定期回顾与优化:定期审查契约内容和测试策略,及时清理过时契约,防止技术债积累。
下面就给大家浅聊一下微服务架构下的契约测试。 2. 5、什么是契约测试(CDC) 契约测试 ,又称之为 消费者驱动的契约测试(Consumer-Driven Contracts,简称CDC),根据 消费者驱动契约 ,我们可以将服务分为消费者端和生产者端 6、契约测试、单元测试、接口测试区别 API测试和单元测试,更强调的是覆盖API内部逻辑。 契约测试 契约测试其实是为了测试服务之间连接或者说接口调用的正确性,为了验证服务提供者的功能是不是真正能够满足消费者的需求。 8、契约测试能给我们带来 降低服务集成的难度,把服务集成这个过程分解成了单元测试和接口测试来做,它从消费者的需求为出发点,把消费者的需求作为你的测试用例驱动出一份契约,然后验证提供者端的功能。
目录: 一、单元测试 二、端到端(系统)测试 三、集成测试 四、使用消费者驱动契约测试(CDCT) 五、总结 一、单元测试 当我们谈到微服务时,我们还应该进行单元测试吗? 消费者驱动契约测试(Consumer-Driven Contracts Testing)背后的理念是定义每个服务消费者与提供者之间的契约,然后根据该契约对消费者和提供者进行独立测试,以验证他们是否符合契约约定的事项 一旦提供者就契约达成协议,消费者和提供者都可以获取契约的副本,并使用测试来验证它们的相应实现没有违反契约。 消费者驱动的契约测试,通常实现方式如下: 1. 生成的契约测试不需要我们编写任何实现代码就可以通过。 并且在测试运行之后,我们会得到一些JSON文件作为存根,类似PACT的契约文件,保存在本地用于应用测试。 PACT (https://docs.pact.io/) 其官网的说明是这样的: PACT是一种契约测试工具。契约测试是一种确保服务(例如API提供程序和客户端)能够相互通信的方法。
本文将从以下几个方面全面解析契约测试: 契约测试是什么? 为什么需要契约测试? 如何进行契约测试? 契约测试的优缺点。 什么是契约测试? 契约测试是一种验证交互点(通常是API接口)在不同服务或组件之间是否按照预定“契约”来执行的测试方法。简单来说,它就像是在服务A和服务B之间建立一份“合同”,规定双方如何交互。 为什么需要契约测试? 传统的集成测试或端到端测试通常是昂贵且耗时的,且可能会漏掉一些边缘情况。契约测试则能更高效、准确地确定问题所在。 如何进行契约测试? 定义契约 首先,我们需要为每个服务定义一个契约。 实施测试 有了契约后,就可以进行实际的测试了。 提供者驱动的契约测试(Provider-Driven Contract Testing): 在这种方法中,提供者根据契约编写测试用例,然后运行这些测试以验证自身是否遵守契约。
方案初想: 根据需求分析和固有测试的瓶颈,通过研究实验,我们引入了一个概念:契约测试。 所谓契约测试,简而言之,即在多个互相依赖的模块之间订立契约(Contract),每个模块都只对契约负责,不关心契约背后消费者(Consumer)。 而消费者则只针对契约依赖,不关注契约背后的服务方(Provider)。 于是,端到端测试便做了衍生,最终结果如下图所示: ? 基于上面表格对比确认,以及和开发讨论,我们最终决定借鉴Sinon.js来快速设计实现我们的契约测试方案。总体流程图如下图所示: ? 左右 后台开发GG不再配置大量回归样式 现网数据 Mock 30s可完全更新 通用性思考 当契约测试接入业务过多的时候,推荐将功能服务器化,做成契约Server 的形式提供,可以相当大的成都节省项目适配成本和维护成本
为什么是契约测试 契约测试(ContractTest)第一次看到我是在Martin Fowler的文章里。 在微服务大行其道的今天,各种服务接口(provider)又被各种服务调用(comsumer),生产者消费者模式就促生了契约测试(更应该叫消费者驱动的契约测试,Cunsumer-Driven Contracts cdc是一种针对外部服务的接口进行的测试,它能够验证服务是否满足消费方期待的契约。 它的本质是从利益相关者的目标和动机出发,最大限度地满足需求方的业务价值实现。 Pact的契约测试流程 ? 如果在执行Provider的测试的时候,就不需要重新完成Provider的测试用例,只需将Pact记录下来的消费者契约作为测试的输入,完成和Provider的交互,来验证Provider是否满足了消费者契约 这也说明了契约测试既不是单元测试也不是集成测试,是处于单元测试和集成测试之间的一层测试行为。
作者 | Rafal Gancarz 译者 | 明知山 策划 | Tina lastminute.com 采用契约测试来降低系统级集成测试所带来的复杂性,并改进反馈周期和开发过程。 最后,经过一些研究和实验,他们采用契约测试作为验证服务间交互正确性的主要方法。 lastminute.com 已经使用 Pact(一个客户端驱动的契约测试工具)对微服务之间的 RPC 交互进行了契约测试,并在随后将其扩展到服务间的异步交互(通过 RabbitMQ 代理交换消息)上。 最后,他们发现了契约测试,生产者和消费者团队可以在他们的测试用例中使用 Mock(或存根)来独立地维护测试套件。 契约测试旨在验证服务之间数据交换的正确性,但服务级集成测试会同时执行业务逻辑和错误处理,确保整个流程 / 数据流的正确性和弹性。
对于单元测试,被测单元只有一个或者很少几个类 ;对于集成测试,你在应用的边界测试应用是否可以连接到一个真实的服务。而要在整个应用的基础上来编写测试,则离不开契约测试。 本文重点阐释使用契约测试来对整个系统进行验证的重要性,以及如何编写契约测试。 理解契约 微服务的架构包含了大量彼此相互通信的微服务。 因此,生产者不需要运行所有消费者的集成测试 ;你只需要测试消费者可以消费符合契约的请求并生成符合契约的响应。 生产和消费者之间的交互 在这个例子中,生产者和所有消费者之间有一个或多个数据相关的契约。 需要注意的是,这时候你依然不需要知道如何启动一个生产者或者启动任何的外部依赖,因为契约的检验无须启动生产者;你只需要检验消费者是否也满足契约的要求。 对契约进行检验的测试也被称为契约测试。 通过本书,读者可以学会如何编写微服务架构下的单元测试、组件测试、集成测试及契约测试。
01 什么是契约测试 测试是软件流程中非常重要,不可或缺的一个环节。一般的测试分为单元测试,集成测试,端到端的手工测试,这也是构成测试金字塔的三个层级。 我们今天将要讨论的话题是契约测试,它是处于单元测试和集成测试中间的一个环节。 这三个层级分别测试的场景如下: 单元测试:测试单个service 集成测试:测试由多个services组成的系统 端到端测试:测试从用户到各个外部系统的整个场景 契约测试的作用: 测试接口和接口之间的正确性 消费者驱动契约测试方法是在消费者和提供者之间定义在它们彼此之间转移的数据格式。通常,合同的格式由消费者定义并与相应的提供商共享。之后,执行测试以验证契约是否相符。 在测试通过后会根据契约返回响应内容。 05 总结 文中首先介绍了契约测试的背景以及基于CDC开发服务的大致过程。
谈到微服务,大家都想到契约测试,到底什么是契约测试呢,为什么要使用契约测试呢,关于这样的文章很多,本文将结合Spring Boot让你了解微服务契约测试。 有了契约测试,只要服务提供者提供契约文件及基于契约文件自动产生的stub模块给服务消费者,服务消费者利用契约文件也产生同样的Stub模块,在服务提供者没有开发可用的真正的程序之前,利用Stub模块进行调试 以上是契约测试的一个优点,把维护stub模块变为了维护契约文件,这样大大地节约开发成本;另外还可以发现接口变动问题。 当某一个接口发生变化,不运行契约测试不知道哪些模块会受到变动的影响,另外最后决定接口是否修改,也是根据fail接口的数量及fail接口的优先等级来决定的。 运行测试文件,验证测试是否满足现在的契约文件。 在这里我使用Spring Boot+cucumber+契约测试文章中的案例 服务生产者Spring Boot pom.xml文件如下: <?
契约测试具体的应用场景包括微服务架构中的前后端分离,前端和后端通过API交互,这时候契约测试可以确保双方的接口一致。 异构系统集成,不同技术栈的服务之间需要交互,契约测试帮助验证接口兼容性。版本升级和兼容性测试,比如API升级到新版本时,确保旧版本客户端不受影响。 应用:通过契约测试(如Pact、Spring Cloud Contract),服务A和服务B团队定义接口的预期行为(请求/响应格式、状态码等)。服务B的测试套件验证其实现是否符合契约。 服务A的测试套件验证其调用逻辑是否符合契约。结果:服务B的变更若破坏契约,测试会立即失败,避免生产环境故障。 应用:将契约测试与文档生成工具结合(如Swagger Codegen)。每次代码变更后,通过契约测试验证文档的准确性。结果:确保文档始终反映真实接口行为。