首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对具有一系列请求和响应的服务使用pact

对具有一系列请求和响应的服务使用pact
EN

Stack Overflow用户
提问于 2017-12-26 08:54:18
回答 2查看 1.1K关注 0票数 1

这里是我的用例:

我的服务是: ServiceA。

它依赖于以下服务: ServicesB和ServiceC。

ServiceA向ServiceB发送一个POST请求,其中包含一些身份验证细节(username+password),而ServiceB则返回一个具有sessionId的json文档。

请求:

代码语言:javascript
复制
POST /authenticate
{
    "username": "_at_api",
    "password": "xxx"
}

响应:

代码语言:javascript
复制
{
    "sessionId": "axy235da7ad5a24abeb3e7fbb85d0ef45f"
}

上面的sessionId用于从ServiceA到ServiceC的所有api调用。

ServiceA请求serviceC使用POST请求启动作业,serviceC返回作业id(字母数字)。

请求:

代码语言:javascript
复制
POST /jobs/local/start
Header: Authentication: axy235da7ad5a24abeb3e7fbb85d0ef45f
{
    ...
}

响应:

代码语言:javascript
复制
{
    "status": "RUNNING",
    "jobId": "a209016e3fdf4425ea6e5846b8a46564abzt"
}

ServiceA一直使用上面返回的serviceC来轮询作业的完成情况:

请求:

代码语言:javascript
复制
GET /jobs/status/a209016e3fdf4425ea6e5846b8a46564abzt
Header: Authentication: axy235da7ad5a24abeb3e7fbb85d0ef45f

响应:

代码语言:javascript
复制
{
    "status": "RUNNING"
}

轮询将继续进行,直到状态返回为已完成或失败为止。

响应:

代码语言:javascript
复制
{
    "status": "COMPLETED"
}

如何使用协约测试serviceA?

我的计划是只使用单元测试和契约测试来实现90%以上的代码覆盖率。这是个好主意,还是我需要使用虚拟服务器进行单独的测试?我的理解是,契约是虚拟服务器(例如:坐骑银行)的超集,而虚拟服务器可以做的任何事情,契约都可以做到。因此,我不需要单独的组件测试。而且,看起来合同测试完全取代了端到端的测试,所以我也不需要端到端的测试。是这样的吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-28 01:53:22

而且,看起来合同测试完全取代了端到端的测试,所以我也不需要端到端的测试。是这样的吗?

不是的。合同测试不是功能测试(请参阅这篇优秀的文章,标题相同)

什么是合同测试?

契约测试是关于测试两个组件是否能够进行通信。

考虑一所房子和一名邮递员之间的合同:邮递员需要知道他们可以上门投递邮件(有时他们可能无法做到这一点--也许邮箱已经满了)。

从邮政工人的角度来看,合同如下:

  • 查找邮箱(有成功和失败案例)
  • 将邮件发送到邮箱(成功和失败案例)

请注意,邮政工作人员对邮筒的实现一无所知。可能有多种原因导致投递邮件失败--也许门被卡住了,可能箱子已经满了,也许邮件太大了,无法装进去。

在这种假设的情况下,我们的邮政工作人员在这些情况下并没有做什么不同的事情--他们只是没有交付。因此,从合同的角度来看,失败的原因是无关紧要的。这份合同--工人可以试着发送邮件,并且他们可以成功或不成功--可以在不列举所有可能的失败原因的情况下进行测试。

有关更详细的示例,请参阅链接在上面一文,但要引用文章末尾的内容:

合同应该是关于捕获:

  • 消费者中的错误
  • 消费者对终点或有效载荷的误解
  • 中断提供者在端点或有效负载上的更改。

契约的一个非常好的特性是,您可以对多个契约进行测试,只对它们所依赖的通信进行测试。

请注意,消费者契约测试只描述消费者需要进行或理解的通信。契约不一定是完整的API描述。

好吧,但是为什么我不能用合同测试来进行端到端的测试呢?

可以使用像契约这样的工具来代替您的端到端测试。然而,尽管合同测试与端到端测试所需的特性有很多相似之处,但合同测试(尤其是契约测试)并不是为端到端测试设计的。

如果您通过扩展现有的用户测试来进行端到端的测试(例如,将所有失败的原因添加到后期工作人员的测试中),那么合同意味着什么就不再清楚了。合同现在描述了通信是如何与行为一起进行的。

当您开始添加更多的消费者(例如,包裹快递员)时,这会导致问题--您是在所有消费者中复制所有的故障案例,还是将它们保留在最初的消费者测试中?如果您复制了测试,那么如果您更改了提供者的行为,那么您需要更改的东西很多--而您的测试将是脆弱的。如果你不重复测试,那么你的端到端测试就会被困在一个消费者身上--如果你解除了这个用户的功能,就会有失去测试的所有问题。

使用纯合同测试,如果要添加消费者已经理解的更多可能的失败原因,则(理想情况下)不必更改任何内容。

如果您尝试这样做,还有很多其他原因会让您头疼(您的测试开始严重依赖于精确的数据,如果您的测试是端到端的测试,那么失败的验证和我能部署挂钩的含义就会改变),但关键的是,契约并不是作为端到端测试的替代品而设计的。您可以这样使用它,但这是不可取的,并可能导致痛苦的维护。

我如何使用契约测试serviceA?

您可以分别描述每个请求,使用Pact提供者状态作为每个请求的先决条件。

此外,您可能会发现关于协议-使用提供程序状态的问题很有帮助。

票数 7
EN

Stack Overflow用户

发布于 2020-07-08 13:34:16

虽然这件事来得很晚,但对于所有偶然发现这件事的人来说:

pact规范(v3.0)只支持每个交互的一个请求(但是每个使用者-提供者-对支持多个交互)。在提供程序方面,每次交互都会产生一个单独的测试。因此,虽然在提供程序端运行序列或请求在概念上不是一个好主意,但它在技术上也不起作用。

然而,在消费者方面,你有一个选择--我鼓励你不要在端到端测试中误用。在我的例子中,我有一个类,它实现了一个包含多个请求的模板/策略模式,并且不允许在使用者端注入中间状态。它要求所有请求都有有效的答复。

在这种情况下,pact-jvm-consumer-junit (=JUnit4 4)允许在单个测试方法上指定多个PactVerification注释(在我的例子中是Kotlin):

代码语言:javascript
复制
@Test
@PactVerifications(
    value = [
        PactVerification("Service B", fragment = "authenticateOk"),
        PactVerification("Service C", fragment = "jobStartOk")
        PactVerification("Service C", fragment = "jobStatusOk")
    ]
)
fun `test successful job execution`() {
 // add your test here.
}

在提供程序端,上面的所有片段都作为单独的测试执行,因此它们需要一个正确的状态,如上面的答案所指定的那样。

我在JUnit4中运行了这种方法。不过,JUnit5还没有找到一种快速的方法来模仿它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47976094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档