对于我们发送数据包(而不是请求)的消息队列,是否应该避免合同测试?

Should contract testing be avoided for message queues where we're sending data packets (not requests)?

似乎合同测试不会为消息队列带来任何好处。有什么好处吗?

在提供者端,我们实例化一个通常进入 kafka 的对象。

所以提供者实质上所做的是:

在消费者端,我们有相反的做法,即我们在内存中重新创建该对象并触发使用它的代码。

换句话说,消费者本质上做的是:

在我的例子中,在消费者方面,无法触发使用对象的代码。这是因为它需要启动服务器本身的实例,这会带来很多复杂性。

当我们发送数据包(不是请求)时,是否应该避免对消息队列进行契约测试?

请务必记住合同测试 =|= 功能测试。 所以我们不会用不同的消息重新测试,因为那将是功能测试。

合同测试的价值

合同测试询问“这些服务是否能够相互通信”。这个问题对于消息队列绝对有价值

部署新版本的消费者安全吗?这取决于生产者是否能够阅读和理解提供者发送的消息。合同测试可以提高您对消费者和提供者能够相互交谈的信心。

您可能会争辩说,合同测试对于消息队列 重要,因为(取决于设计以及消息在 queues/whether 中的重放时间),您可能正在使用由多个不同版本的生产者生成的消息。

即使消费者和提供者在同一个部署单元中(例如,单个微服务),您也可能在部署发生后立即使用来自以前版本的提供者的消息。

理论

从理论上讲,测试消息队列的合约就像测试 HTTP request/response 对的合约,其中请求是隐式的(您可以争辩说“请求”是对队列的订阅)。

练习

当 testing/verifying HTTP Pact 合同时,Pact 提供传输(模拟 HTTP client/server)和内容(内容形状和约束)。

目前,当使用消息 Pact 进行相同的测试时,Pact 仅提供内容/约束。没有模拟 consumer/provider - Pact 框架未测试数据传输。这意味着消息协议测试的覆盖率略低于相应的 HTTP 协议——它不会测试您的队列库是否已正确设置和调用(除非您自己进行测试)。

Pact Spec V4 Plugin proposal 的存在是为了让将来更容易解决这个差距,这样消息 pact 测试也将能够更轻松地覆盖队列库。但是,它不是今天可以使用的东西。

您的具体情况

it requires starting an instance of the server itself which introduces a lot of complexity.

感觉这可能是一个软件设计问题,稍微重构一下就可以解决。您应该能够 运行 消息契约消费者测试而无需启动整个服务器。这将特定于您的用例和设计,但在 https://slack.pact.io/ 加入我们 #general,我们可能会帮助您。

合同测试不是功能测试

It is important to keep in mind that Contract Testing =|= Functional Testing. So we're not going to retest with different messages because that would be functional testing.

是的,这是一个很好的观察。一般来说,你想要测试你的消费者是否能够理解提供者可以发送的每一种类型的消息,而在消息队列的情况下,这通常只是一种类型(尽管有时仍然是几种)。

这有点偏离你的问题的主题,但这里有一个小警告,虽然 Pact 测试不是功能测试,但如果它有一些功能 覆盖率.所有测试都是为了降低风险 - 您越接近测试您将要 运行 的实际代码,风险就降低得越好。出于这个原因,我通常会尽可能深入地在服务中放置任何模拟。当然,我会用它自己的单元测试来覆盖服务的行为,但我认为如果 pact 测试(不直接覆盖行为)恰好在合同验证过程中仍然执行一些行为,那就太好了.如果您需要,很乐意详细说明。