对微服务之间的协定进行自动测试?



假设我们有一个依赖于 ThreeDSecureService 微服务的 CreditCardService 微服务,使用 JSON 进行通信。

ThreeDSecureService的API(甚至实现(的微小变化可能会悄无声息地破坏CardCardService(和其他潜在客户(。因此,我们想要自动测试。

我看到了两种有缺陷的方法,我想知道如何改进。

  1. ThreeDSecureService.Tests中的集成测试。

ThreeDSecureService附带的测试项目可以有一个带有固定JSON输入的集成测试。伪造任何依赖项,它可以对该输入运行其他完整的调用,确认服务吞噬了输入。

这里的问题是,如果有人没有意识到他们的更改如何破坏客户端,他们几乎同样有可能"修复"测试以匹配他们的更改。

  1. CreditCardService.Tests中的集成测试。

客户端是真正想要测试有关 ThreeDSecureService 预期输入的断言的客户端。但是,这将要求客户解决方案包括ThreeDSecureService项目以及它所依赖的任何项目。这将抵消我们从使用微服务中获得的许多优势!

我们如何从客户端做出断言(保护依赖关系(,而不会破坏我们使用微服务获得的松散耦合?

我希望我已经理解了你的问题,但如果不是这样,以下内容至少有助于你的想法。

我理解你的问题的方式是非常实际的,即"我如何组织解决方案和项目,以最大限度地降低开发人员在不了解服务消费者对服务消费者的影响的情况下违反服务合同的风险?

在理想的世界中,开发人员不会这样做。如果他们对服务进行了重大更改,他们就知道自己已经完成了更改,并且这是一个新版本。话虽如此,我明白你的意思 - 对这种人为错误采取某种保护措施是很好的,因为开发人员在大多数情况下都是完美的。

如果你在一个环境中工作,在那里你正在创建其他团队所依赖的微服务,反之亦然,那么就没有办法绕过一个有纪律和结构化的方法,即适当的治理。镜像生产的完整测试环境,其中所有服务都在运行,您可以测试您的服务是否与它所依赖的服务很好地集成也不会受到伤害。

如果您控制了所有需要相互通信的服务,那么(至少在我看来(您没有理由不应该拥有一个包含所有服务项目并且您的集成测试项目启动所有服务并检查它们之间的集成是否按预期工作的解决方案。

除了合约/接口之外,你的个人微服务不应该了解外部世界的任何信息,你应该有单元测试来隔离测试每个微服务,模拟依赖项。

如果一个解决方案变得太大,则可以将其分解为较小的部分,对于包含该服务及其最近邻居的每个服务,可以将其分解为一个解决方案。在您的示例中,这可能是包含 ThreeDSecureService、CreditCardService 和 CardCardService.IntegrationTests(测试 CardCardService,而 ClientCardService,而 ClientCardService,而 ClientCardService,而 CapitalCardService( 则调用 ThreeDSecureService(的解决方案。 这样,当开发人员在ThreeDSecureService上工作时,集成测试将让开发人员知道他/她已经破坏了集成。 当然,这仍然需要开发人员记住实际运行集成测试。

在我看来,最终目标是将一个门合并到您的构建流程中,以确保开发人员无法发布会导致集成测试失败的更改,以及自动部署。这将确保基本集成错误不会进入生产环境。

为避免破坏集成,请使用公共合约。例如,RAML。描述特定服务的客户端将获取和传递的模型,描述操作和参数。在这种情况下,没有人依赖于特定的服务或实现,双方只需要测试他们与合同的通信。

其他安全措施是将合同发布为 dll。在这种情况下,服务的使用者会在一分钟内注意到变化。如果他们有单元测试,他们可能会更早地显示任何问题。

作为保持分离的主要规则:不要引用实现,而是引用合约。