Pact JS:提供商测试

时间:2017-11-29 04:31:57

标签: javascript pact pact-broker

使用Pact JS测试我的消费者和提供者。我已经成功生成了一个pact文件,我想验证那些针对我的提供者的文件。

关于测试提供商,我有几个问题:

  1. 在进行测试之前,是否需要启动提供商服务?我应该在测试中击中实际的提供者端点吗? 例如,假设我的提供商代码库中有GET / dogs端点。当我运行我的测试时,是否需要在本地启动我的服务,点击/ dogs端点然后使用pact文件验证为端点返回的响应?
  2. 如果我想将其作为CI管道的一部分运行(我正在使用CircleCI),那么有哪些最佳实践可以遵循?我是否需要从circleci构建步骤启动我的服务,指向某处的某个数据库,然后按照上述步骤操作?
  3. 是否有任何关于在提供程序测试中使用存根的概念?如果是这样,这些如何用于盯着提供者服务。是否有任何示例或示例代码?

1 个答案:

答案 0 :(得分:3)

  

在进行测试之前,是否需要启动提供商服务?我应该在测试中击中实际的提供者端点吗?

是的,您启动了提供商,并使用实际端点(请参阅下面的警告)

  

当我运行我的测试时,是否需要在本地启动我的服务,点击/ dogs端点然后使用pact文件验证端点返回的响应?

排序。 Pact的模拟消费者会对端点进行命中,并将结果与​​pact文件中的预期响应进行比较。

  

如果我想将其作为CI管道的一部分运行(我正在使用CircleCI),那么有哪些最佳实践可以遵循?

这是一个普遍的问题,但您通常会创建一个构建步骤来启动服务,运行Pact的验证,然后取消服务。请参阅帖子的结尾以获取示例链接。

  

是否有任何关于在提供程序测试中使用存根的概念?如果是这样,这些如何用于盯着提供商服务?

因此,pact是一种合同测试工具。合同测试has some important differences from functional testing

从广义上讲,合同测试是关于验证您发送和接收的数据的形状是否已达成一致并且双方都能理解。它不是要验证数据是否正常运行。假设我有一个API,它采用代表电话号码的字符串:

  • 添加本地电话号码有效
  • 使用国内拨号代码添加电话号码是有效的
  • 使用国家/地区拨号代码添加电话号码是有效的
    • 可以从+00
    • 开始
  • 在开头以外的任何地方添加+的电话号码无效
  • 在一定长度内添加电话号码无效

尽管那里有很多案例,但Pact只有成功和失败的情况才适合:

  • 尝试添加有效的电话号码 - >无论成功的反应是什么
  • 尝试添加无效的电话号码 - >无论电话号码响应无效。

(当然,除非API针对不同类型的失败返回不同的响应)。

合同是关于可以表达的内容,而不是表达的原因。

这告诉我们在哪里可以使用存根 - 您的API端点工作流可能看起来像这样,在伪代码中:

// end point for "add phone number"
request = unmarshalResponse(data)
success = recordPhoneNumber(request)
response = marshallResponse(success)
send(response)

因为我们只对合同感兴趣,所以在recordPhoneNumber()中隐藏业务逻辑是合适的,这意味着该协议将测试您的网络层和您的编组人员。

根据您的代码设计,放置该存根的最佳位置将会发生变化。在我们的示例中,存根看起来像这样:

// stub for recordPhoneNumber()
if (request.phoneNumber === "+12 345 1234 123") {
   return new Valid()
} else if (request.phoneNumber === "123") {
   return new Invalid("Number too short")
}

理想情况下,合同测试不需要在端点之外的任何基础架构(数据库,缓存等)。所以,理想情况下,你可以将你的存根放在一个你不需要启动这些东西的地方。

Pact不适合使用集成测试工具(虽然可能以这种方式使用它,如果你这样做,你会遇到其他问题)。

  • 但我的提供商如何知道要应用哪个存根?

您可以使用provider states实现此目的。以下是javascript provider example

中的一个真实示例
server.post('/setup', (req, res) => {
  const state = req.body.state

  animalRepository.clear()
  switch (state) {
    case 'Has no animals':
    // do nothing
    break
   default:
    importData()
  }
}
  

是否有任何示例或示例代码?

是。看看这个javascript provider example