如何使用 pactjs 处理不同环境的不同路径参数

How to handle different path parameters for different environments using pactjs

我已经开始为 CDC 测试实施 PACT。如何处理我们在不同环境的路径中传递不同参数的情况?

例如,我的测试调用了一个函数,该函数通过访问端点并传递一些参数来从服务请求一些数据。很标准。

例如:api/nodeId/${nodeId}/userId/${userId}

对于不同的环境(QA、UAT 等),必须传递特定于该环境的唯一数据才能引发有效的 200 响应。因此,在我的示例中,每个环境的 carId 和 userId 都需要不同。当我最初设置测试时,我使用了我们的 QA 环境并生成了以下合同。

{
  "consumer": {
    "name": "myConsumer"
  },
  "provider": {
    "name": "myProvider"
  },
  "interactions": [
    {
      "description": "a request to view nodes",
      "request": {
        "method": "GET",
        "path": "/api/nodeId/RRTT6-3AFA-4B5B-BF76-5B6AC7/userId/123456789",
        "headers": {
          "Content-Type": "application/x-www-form-urlencoded",
        }
      },
      "response": {
        "status": 200,
        "headers": {
          "Content-Type": "application/json"
        },
        "body": {
          "startTime": 1549652248000,
          "endTime": 1549911448000,
          "startPrice": 83576,
          "reservePrice": 83876,
          "price": 84576,
          "status": null,
          "groupList": [
            "78945"
          ],
          "bids": 0,
        }
      }
    }
  ],
  "metadata": {
    "pactSpecification": {
      "version": "2.0.0"
    }
  }
}

如您所见,合约中的路径具有硬编码的 nodeId 和 userId。如果我尝试针对不同的环境进行验证,这些测试将会失败。那么我怎样才能在不同的环境中重复使用相同的合同呢?目前对于不同的环境,我正在为每个环境生成一个单独的合同,但似乎必须有另一种方式。

依赖外部环境变量来 运行 你的测试通常不是一个好主意,主要是因为使用客户端驱动合同的优点之一是你的生产者可以被隔离测试,甚至可以隔离环境。这意味着您的测试应该设置它所依赖的东西或者是灵活的而不依赖于特定的环境配置。这是任何自动化测试都应该做的,而不仅仅是 CDC。

在您的场景中,例如,您可以在测试开始之前创建合同中指定的用户,或者将您的用户适配器模拟为 return 一个有效用户,无论用户 ID 是否通过。这里的答案将取决于您的消费者如何使用 nodeIduserId.

您可以将 term Matcher 用于动态路径,但正如 Fabrico 警告的那样,每个环境都有特定的数据是玩危险的游戏。由于各种原因,提供程序具有不同的 ID 是很常见的,因此请尽可能尝试将您的测试与这些 ID 分开。

例如使用路径匹配器:

const { Pact, Matchers } = require('@pact-foundation/pact');
const { term } = Matchers;

provider.addInteraction({
  state: 'has node ID 1234 and user with ID 5678',
  uponReceiving: 'a request to view nodes',
  withRequest: {
    method: 'GET',
    api/nodeId/${nodeId}/userId/${userId}
    path: term({ generate: '/api/nodeId/RRTT6-3AFA-4B5B-BF76-5B6AC7/userId/123456789', matcher: '/api/nodeId/[A-Z0-9\-]+/userId/[0-9]+' })
  },
  willRespondWith: {
    status: 200,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: { ... }
  }
})

提供商验证通常是 运行 针对本地计算机或持续集成构建节点上的本地 运行ning 提供商。它不打算 运行 针对已部署的环境,并且它在某种程度上违背了像那样使用它的目的。合同测试的优势在于,您应该在部署之前 了解这些服务是否可以协同工作。加入我们 slack.pact.io 如果您对此感到困惑,请与我们交谈。