”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 消费者驱动的合同测试指南

消费者驱动的合同测试指南

发布于2024-10-31
浏览:155

A Guide to Consumer-Driven Contract Testing
在现代微服务架构中,应用程序严重依赖服务间通信(通常通过 API)。确保这些 API 在开发期间和更改后继续按预期工作至关重要。实现这一目标的一种有效方法是通过消费者驱动的契约测试(CDCT)。 CDCT 是一种确保服务(生产者)遵守使用其 API 的服务(消费者)设定的期望的方法。

在本指南中,我们将探讨 CDCT 是什么、它是如何工作的、它在确保可靠的微服务交互方面的重要性,以及如何使用 Pact 等工具来实现它。

什么是消费者驱动的契约测试?
消费者驱动的合同测试是一种测试策略,可确保分布式架构中的服务之间的通信遵守商定的合同。它与传统的 API 测试不同,它关注消费者的需求,而不仅仅是确保 API 本身正常运行。 API 消费者和提供者之间的契约是由消费者的期望定义的,并且该契约根据提供者的实现进行验证。

关键术语:
• 消费者:使用API​​ 的服务。
• Provider(生产者):提供API的服务。
• 合同:消费者和提供商之间的正式协议,指定预期的 API 行为。

它是如何工作的?

  1. 消费者定义合约: 消费者定义其对提供商 API 应如何表现的期望(例如,其期望的端点、数据格式和响应状态代码)。
  2. 合同是共享的: 消费者与提供商共享此合同。该合同作为提供商必须满足的规范。
  3. 提供商验证合同: 提供商根据消费者的合同进行自我测试,确保其满足消费者的期望。
  4. 持续反馈循环: 提供商 API 的任何重大更改都将被尽早发现,因为提供商必须根据所有消费者的合约进行验证。这创建了一个安全网,以确保提供商的变化不会对消费者产生负面影响。

消费者驱动的合约测试的重要性
在分布式架构中,尤其是微服务,管理服务之间的依赖关系变得更加复杂。 CDCT 通过多种方式帮助减轻这种复杂性:

1.防止生产中的损坏
由于消费者定义了他们的需求,因此供应商 API 的更改如果不满足消费者的期望,就会在开发流程的早期被捕获。这降低了由于不兼容的更改而破坏生产系统的风险。

2.解耦开发
消费者驱动的契约测试允许消费者和提供商独立开发。当团队或服务单独发展时,这尤其有用。合约充当接口,确保集成按预期工作,无需在每个开发周期进行完整的集成测试。

3.更快的开发周期
通过 CDCT,消费者和提供商都可以并行开发和测试,从而加快开发速度。即使在消费者完全实现其功能之前,提供商也可以针对消费者的合约进行测试。

4。及早发现合同违规行为
在开发过程的早期检测到违反合同的提供商变更,使开发人员能够在问题变得严重之前解决问题。

如何实施消费者驱动的合约测试
有多种工具可用于实施 CDCT,其中 Pact 是最流行的工具之一。 Pact 允许消费者定义他们的合同并允许提供商验证它们。

以下是使用 Pact 实施 CDCT 的分步指南:
第 1 步: 定义消费者期望
首先,在消费者服务中,定义契约。这通常包括以下内容:
• 消费者将调用的端点。
• 请求方法(GET、POST、PUT 等)。
• 预期的请求正文或参数。
• 预期的响应正文和状态代码。
以下是在 JavaScript 中使用 Pact 在消费者测试中定义合约的示例:

const { Pact } = require('@pact-foundation/pact');
const path = require('path');

const provider = new Pact({
    consumer: 'UserService',
    provider: 'UserAPI',
    port: 1234,
    log: path.resolve(process.cwd(), 'logs', 'pact.log'),
    dir: path.resolve(process.cwd(), 'pacts'),
});

describe('Pact Consumer Test', () => {
    beforeAll(() => provider.setup());

    afterAll(() => provider.finalize());

    it('should receive user details from the API', async () => {
        // Define the expected interaction
        await provider.addInteraction({
            state: 'user exists',
            uponReceiving: 'a request for user details',
            withRequest: {
                method: 'GET',
                path: '/users/1',
                headers: {
                    Accept: 'application/json',
                },
            },
            willRespondWith: {
                status: 200,
                headers: {
                    'Content-Type': 'application/json',
                },
                body: {
                    id: 1,
                    name: 'John Doe',
                },
            },
        });

        // Make the actual request and test
        const response = await getUserDetails(1);
        expect(response).toEqual({ id: 1, name: 'John Doe' });
    });
});

在此示例中,消费者 (UserService) 希望提供者 (UserAPI) 在向 /users/1 发出 GET 请求时返回用户详细信息。

第2步:发布合约
一旦消费者测试通过,Pact 就会生成一个可以与提供者共享的合约文件(Pact 文件)。该合约可以存储在 Pact Broker 或版本控制系统中,以便提供商可以使用它进行验证。

第 3 步:提供商验证合同
提供商检索合同并验证其是否符合消费者的期望。这是通过在提供商端运行 Pact 测试来完成的。下面是用 Java 验证 Pact 合约的示例:

public class ProviderTest {

    @Test
    public void testProviderAgainstPact() {
        PactVerificationResult result = new PactVerifier()
            .verifyProvider("UserAPI", "pacts/UserService-UserAPI.json");

        assertThat(result, instanceOf(PactVerificationResult.Ok.class));
    }
}

提供商运行此测试以确保其遵守消费者指定的合同。

第四步:持续集成
一旦 CDCT 集成到您的 CI/CD 管道中,每次合同更改时,提供商都可以自动验证合同。这确保 API 更改不会打破消费者的期望,为两个团队提供安全网。

CDCT 最佳实践

  1. 小型、集中的合同: 确保您的合同规模较小,并且仅关注消费者的需求。这可以防止合同中不必要的复杂性并简化验证。
  2. 合同版本控制: 始终对合同进行版本控制。这允许提供商处理同一合同的多个版本,帮助您支持处于不同开发阶段的不同消费者。
  3. 独立部署: 确保 CDCT 是 CI/CD 管道的一部分。对消费者或提供商的任何更改都应触发合同测试,以避免破坏生产环境。
  4. 使用 Pact Broker: Pact Broker 是一个中央存储库,用于存储您的合同并允许消费者和提供商检索它们。它还提供了一个用于可视化合约版本和依赖项的 UI。

何时使用消费者驱动的契约测试
CDCT 在以下情况下特别有用:
• 您拥有具有多个交互服务的微服务或分布式架构。
• 从事不同服务的团队需要独立开发,无需频繁的集成测试。
• API 合同可能会经常更改,您希望避免打破消费者的期望。
• 您需要快速反馈循环来在开发过程的早期检测合同违规行为。

结论
消费者驱动的契约测试提供了一种可靠的方法来确保分布式系统中的服务有效通信而不破坏更改。通过关注消费者的期望并根据这些期望验证提供商,CDCT 帮助团队独立开发,同时确保稳定性。无论您是构建微服务、基于 API 的应用程序还是分布式系统,将 CDCT 纳入您的测试策略都将提高服务的可靠性和可扩展性。

版本声明 本文转载于:https://dev.to/keploy/a-guide-to-consumer-driven-contract-testing-2dho?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 混淆技术真的可以保护可执行文件免受逆向工程的影响吗?
    混淆技术真的可以保护可执行文件免受逆向工程的影响吗?
    保护可执行文件免遭逆向工程:解决方案有限的挑战保护代码免遭未经授权的逆向工程是开发人员持续关注的问题,尤其是当它包含敏感信息。虽然已经提出了各种方法,但重要的是要承认完全防止逆向工程实际上是不可能的。常见混淆技术用户建议的策略,例如代码注入、混淆和自定义启动例程的目的是使反汇编变得不那么简单。然而,...
    编程 发布于2024-11-08
  • 掌握 Laravel 中的 Eloquent where 条件
    掌握 Laravel 中的 Eloquent where 条件
    Laravel 的 Eloquent ORM(对象关系映射)是其突出的功能之一,提供了一种与数据库交互的强大而富有表现力的方式。 Eloquent 提供的一项基本功能是方法,它允许开发人员高效、直观地过滤查询。在本文中,我们将深入研究 where 条件,探索其各种形式和实际用例。 ...
    编程 发布于2024-11-08
  • 在 Gmail 的 Chrome 12+ 更新中如何从剪贴板粘贴图像?
    在 Gmail 的 Chrome 12+ 更新中如何从剪贴板粘贴图像?
    将剪贴板中的图像粘贴到 Gmail:Chrome 12 中的操作方法 Google 宣布能够将剪贴板中的图像直接粘贴到 Gmail使用 Chrome 12 的 Gmail 引发了人们对其底层机制的好奇。尽管使用了最新的 Chrome 版本,一些用户仍然无法找到有关如何在 Webkit 中实现此增强功...
    编程 发布于2024-11-08
  • JavaScript 演示场景竞赛 - JS 版
    JavaScript 演示场景竞赛 - JS 版
    JS1024 于 2024 年回归! 准备好迎接激动人心的挑战! JS1024 回归,通过在 JavaScript、HTML 或 GLSL 中创建令人惊叹的演示(全部在 1024 字节限制内),将开发人员推向极限。无论您是经验丰富的编码员还是新手,这都是您展示创造力和技术技能的机会...
    编程 发布于2024-11-08
  • 第九届 TCmeeting 的更新
    第九届 TCmeeting 的更新
    议程上有几个项目,本文重点介绍第 104 次 TC39 会议 [2024 年 10 月 8 日至 10 日] 的功能提案及其进展。 第一阶段: 表示度量:建议在 JavaScript 中使用适当的单位格式化和表示度量。 Immutable ArrayBuffers:添加 ArrayB...
    编程 发布于2024-11-08
  • 如何使用 CSS 在图像地图上实现鼠标悬停效果?
    如何使用 CSS 在图像地图上实现鼠标悬停效果?
    使用 CSS 设置图像地图鼠标悬停样式创建交互式网页时,通常需要包含具有可单击区域的图像。通常,这是使用图像映射来实现的。然而,事实证明,在鼠标悬停时设置这些区域的样式以提供额外的交互性是难以实现的。过去,尝试使用 CSS 设置这些区域的样式所取得的成功有限,如提供的示例所示:<img src...
    编程 发布于2024-11-08
  • 升级您的前端游戏:无头和静态未来的学习框架
    升级您的前端游戏:无头和静态未来的学习框架
    前端领域正在以惊人的速度发展。忘掉笨重、单一的网站吧——未来属于无头 CMS 和静态网站生成器 (SSG)。这些时尚的强大功能提供了无与伦比的速度、灵活性和安全性,但征服它们需要使用正确的工具。 为了利用他们的力量,开发人员正在转向 Next.js 和 Gatsby,这两个尖端的前端框架塑造了我们...
    编程 发布于2024-11-08
  • 如何修复 PyGame 动画闪烁:故障排除和解决方案
    如何修复 PyGame 动画闪烁:故障排除和解决方案
    PyGame 动画闪烁:故障排除和解决方案运行 PyGame 程序时,您可能会遇到动画闪烁的问题。这可能会令人沮丧,特别是如果您不熟悉使用该框架。PyGame 中动画闪烁的根本原因通常是多次调用 pygame.display.update()。不应在应用程序循环中的多个点更新显示,而应仅在循环结束时...
    编程 发布于2024-11-08
  • JavaScript 中的声明式编程与命令式编程
    JavaScript 中的声明式编程与命令式编程
    当谈到编程方法时,经常会出现两种常见的方法:声明式编程和命令式编程。每个都有其优点和理想的用例,尤其是在 JavaScript 中。让我们通过一些例子来探讨这两种风格。 命令式编程:告诉计算机如何做 命令式编程就像给出一组详细的指令。你告诉计算机如何一步步达到特定的结果。将其视为指导...
    编程 发布于2024-11-08
  • 掌握 NestJS 中的数据验证:类验证器和类转换器的完整指南
    掌握 NestJS 中的数据验证:类验证器和类转换器的完整指南
    Introduction In the fast-paced world of development, data integrity and reliability are paramount. Robust data validation and efficient handl...
    编程 发布于2024-11-08
  • 有多少 Python 包的版本控制正确?
    有多少 Python 包的版本控制正确?
    前几天,当我研究Python包中的漏洞数据库时,我意识到其中的一些包版本无法轻松解析并与其他版本字符串进行比较,因为它们不遵守Python 版本控制 - 旧的 PEP 440 或取代它的版本说明符规范。所以我开始想知道这种情况有多普遍。 Python 包索引上有多少包实际上具有有效版本? 显而易见的...
    编程 发布于2024-11-08
  • 如何在 Web 应用程序中有效地对 Ajax 请求进行排序?
    如何在 Web 应用程序中有效地对 Ajax 请求进行排序?
    排序 Ajax 请求在许多 Web 应用程序中,通常会遇到需要迭代集合并对每个元素发出 Ajax 请求的情况。虽然利用异步请求来避免浏览器冻结很诱人,但有效管理这些请求可以防止服务器过载和其他潜在问题。jQuery 1.5 对于 jQuery 1.5 及更高版本,$. ajaxQueue() 插件提...
    编程 发布于2024-11-08
  • JavaScript 中“%”运算符的作用是什么?
    JavaScript 中“%”运算符的作用是什么?
    揭开 JavaScript 中 % 运算符的本质JavaScript 中神秘的 % 符号被称为模运算符。它在数学运算中发挥着关键作用,它返回一个操作数除以另一个操作数后的余数。模运算符通常表示如下:var1 % var2其中var1 和 var2 代表操作数。例如,如果我们有表达式 12 % 5,结...
    编程 发布于2024-11-08
  • 检测过时的描述
    检测过时的描述
    开发人员文档通常在每个文件中包含说明。这些描述可能会过时,导致混乱和不正确的信息。为了防止这种情况,您可以使用一些 AI 和 GenAIScript 自动检测文档中过时的描述。 Markdown 和 frontmatter 许多文档系统使用 markdown 格式来编写文档,并使用“...
    编程 发布于2024-11-08
  • Java性能优化技术
    Java性能优化技术
    你好 ? 您可以找到有关 Java 性能优化技术 的完整文章 1. 概述 优化您的代码性能对于您的个人资料的成功至关重要。您是否知道 Akamai 的研究发现,如果页面加载时间超过 3 秒,57% 的在线消费者就会放弃网站?在这篇文章中,您将学习如何优化 Java 代码并提高代码性能...
    编程 发布于2024-11-08

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3