假设我们有一个依赖于ThreeDSecureService微服务的CreditCardService微服务,使用JSON进行通信。
ThreeDSecureService的API(甚至实现)中的微小变化可能会无声地破坏CreditCardService(以及其他潜在客户端)。所以,我们希望自动化测试。
我看到两种有缺陷的方法,我想知道如何改进。
ThreeDSecureService的附带测试项目可以使用固定的JSON输入进行集成测试。伪造任何依赖关系,它可以运行一个完整的输入调用,确认该服务吞下输入。
这里的问题是,如果某人未能意识到他们的变化如何破坏客户,他们几乎就有可能解决问题。测试以匹配他们的变化。
客户端实际上是想测试有关ThreeDSecureService的预期输入的断言。但是,这需要客户端解决方案包含ThreeDSecureService项目以及它所依赖的任何项目。这将否定我们使用微服务所带来的许多好处!
我们如何在不破坏使用微服务的松散耦合的情况下从客户端进行断言(保护依赖性)?
答案 0 :(得分:1)
我希望我已经理解了你的要求,但如果不是,那么以下内容至少对你的想法有所贡献。
我理解你的问题的方式是非常实用的,即“我如何组织解决方案和项目,以最大限度地降低开发人员违反服务合同的风险,而不了解它对该服务的消费者会产生什么影响? “
在理想的世界中,开发人员不这样做。如果他们对服务进行重大更改,他们就知道他们已经完成了,并且它是一个新版本。话虽如此,我明白你的观点 - 对于那种人为错误有一定的保障是很好的,因为开发人员大多数时候都是完美的。
如果你在一个环境中工作,你正在创建其他团队所依赖的微服务,反之亦然,那么就没有办法采用规范和结构化的方法,即适当的治理。一个完整的测试环境,可以反映生产,所有服务都在运行,您可以测试您的服务是否与其所依赖的服务完美集成,也不会造成损害。
如果您掌控所有需要相互沟通的服务,那么(至少在我看来)没有理由不应该有一个解决方案,其中包含您的所有服务项目以及集成测试项目启动它需要的所有服务,并检查它们之间的集成是否按预期工作。
除了合同/接口之外,您的个人微服务不应该对外部世界有任何了解,您应该进行单元测试,单独测试每个微服务,模拟依赖关系。
如果一个解决方案变得太大,您可以将其分解为更小的部分,针对包含服务及其最近邻居的每个服务的一个解决方案。在您的示例中,这可能是一个包含ThreeDSecureService,CreditCardService和CreditCardService.IntegrationTests(它测试CreditCardService,后者又调用ThreeDSecureService)的解决方案。 这样,当开发人员正在使用ThreeDSecureService时,集成测试将让开发人员知道他/她已经破坏了集成。 这仍然需要开发人员记住当然要记住实际运行Integration测试。
我认为最终目标是在构建流程中加入一个门,以确保开发人员无法发布可能导致集成测试失败的更改,以及自动部署。这将确保基本的集成错误不会使其投入生产。
答案 1 :(得分:0)
为避免破坏集成,请使用公共合同。例如,RAML。描述特定服务的客户端将获取并传递的模型,描述操作和参数。在这种情况下,没有人依赖于特定的服务或实施,双方都需要测试他们与合同的沟通。
额外的安全措施是将您的合同发布为dll。在这种情况下,服务的消费者会注意到一分钟内的变化。如果他们有单元测试,他们可能会更早地显示任何问题。
作为保持脱钩的主要规则:不要参考实施,而是参考合同。