在进行测试之前,我是否需要启动我的提供者服务?我应该在测试中点击实际的提供者端点吗?
是的,您启动您的提供程序,并使用实际的端点(请参阅下面的警告)
当我运行我的测试时,我是否需要在本地启动我的服务,点击 /dogs 端点,然后使用 pact 文件验证为端点返回的响应?
有点。Pact 的模拟消费者将为您完成端点的命中并将结果与 pact 文件中的预期响应进行比较。
如果我想将其作为 CI 管道的一部分运行(我正在使用 CircleCI),有哪些最佳实践可以遵循?
这是一个普遍的问题,但您通常会创建一个构建步骤来启动服务、运行 Pact 的验证,然后关闭服务。请参阅文章末尾的示例链接。
有没有在提供者测试中使用存根的概念?如果是这样,这些如何用于启动提供者服务?
所以,pact 是一个合约测试工具。合同测试与功能测试有一些重要的区别。
从广义上讲,合同测试是关于验证您发送和接收的数据的形状是否已达成一致,并且双方都可以理解。这与验证数据的行为是否正确无关。假设我有一个 API 的以下设计,它接受一个代表电话号码的字符串:
- 添加本地电话号码有效
- 电话号码添加国家区号有效
- 电话号码添加国家区号有效
- 添加电话号码
+
的开头不是开头的电话号码是无效的
- 添加一定长度以下的电话号码无效
尽管那里有很多案例,但 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 不太适合集成测试工具(尽管可以这样使用它,但如果这样做会遇到其他问题)。
您可以通过提供者状态来实现这一点。这是来自javascript 提供程序示例的真实示例:
server.post('/setup', (req, res) => {
const state = req.body.state
animalRepository.clear()
switch (state) {
case 'Has no animals':
// do nothing
break
default:
importData()
}
}
是否有任何示例或示例代码?
是的。查看这个javascript 提供程序示例