集成测试:模拟外部API vs 使用外部API沙盒

26

我们需要使用外部合作伙伴的API。该API状态良好,我们已经获得了一个沙箱环境,可以用于自动测试。

我们已经使用单元测试测试了每个外部API调用,但对于涉及外部合作伙伴一侧的复杂操作的集成测试最佳实践还不确定。

例如:我们服务的每个用户在我们的外部合作伙伴那里也有一个用户对象。当对该用户对象执行外部API调用X时,我们希望此用户的Z集合中出现Y对象(我们必须使用不同的调用进行查询)。

这种情况下的最佳测试实践是什么?

  • 尽可能模拟外部API请求 并依赖于单元测试来完成工作?优点:测试运行速度快,不受互联网连接的影响。缺点:我们的模拟错误可能导致误报。

  • 集成外部API沙箱 并针对其运行每个集成测试。优点:接近实际的API交互。缺点:测试只能在开放的互联网连接下运行,并且需要更长时间。

  • 使用混合方法使用模拟和沙箱数据,设置一个布尔值以在需要时在内部(=模拟)和外部(=沙箱)环境之间切换。优点:可靠的测试。缺点:可能很难设置。

  • 其他最佳实践?

谢谢!


相关:如何编写与外部API交互的集成测试? 但是,答案“您不会。您必须实际相信实际的API确实有效。”在我们看来是不足够的。

[编辑] 我们担心只针对我们对外部API的工作方式的假设进行集成测试(即使它们基于单元测试)-而不是针对实际API-将给我们留下错误的正面结果。我们需要的是一种测试,验证我们的假设(模拟)是否正确 - 不仅在单元测试的情况下,而且在涉及多个步骤的复杂操作的情况下。

验证可能是一个很好的例子:如果我们搞砸了集成代码并发送畸形数据或者在我们发送数据时上下文中没有任何意义的数据,因为我们错过了某个步骤,那么怎么办?我们的模拟API不会验证(或只在非常有限的范围内验证),仍然会返回有效数据,而不是传递我们从真正的API收到的错误。


你没有解释为什么答案不足够。因此,我们不知道为什么那个答案在你的情况下不适用,也不知道如何回答你的问题。 - Raedwald
可能是如何编写与外部API交互的集成测试?的重复问题。 - Raedwald
谢谢,你是正确的,我应该更详细地阐述。我刚才已经扩展了最后一部分,并加入了更多的背景。 - zerodot
1个回答

20

我认为当我们与外部API进行接口时,需要进行两个级别的验证:

  • API验证:验证API是否按照其规格和/或我们的理解工作
  • 应用程序功能验证:验证我们的业务逻辑是否按照通过API验证的API的期望工作

在我们的情况下,我们使用模拟API(mock API)以及真实和模拟API验证(real and mock API verification)

  • 模拟API使我们能够将任何运行时错误/异常隔离到仅与应用程序功能有关,因此我们不会因问题而责怪任何外部方
  • 相同的API验证针对真实API和模拟API执行,以确保真实API按照我们的期望工作,同时模拟API应正确地模仿真实API

如果在过程中,外部API发生变化,API验证可能会变成红色,触发对模拟API的更改。模拟API的更改可能导致应用程序验证变成红色,从而触发对应用程序实现的更改。这样您就永远不会错过外部API和应用程序实现之间的任何差距(理想情况下)。

拥有模拟API + API验证的另一个额外好处是,您的开发人员可以将其用作API应该如何工作的文档/规格说明。


2
谢谢,听起来是个不错的方法。这个答案只是基于你的经验吗?还是有外部资源可以参考的? - zerodot
这实际上是我们现在正在做的事情,用于测试使用外部API的Android应用程序。对于模拟服务器,我们使用sinatra因其简单易用性。对于API验证,我们使用cucumberrest-client的组合来创建BDD API测试。我们曾经使用沙盒服务器进行测试,但它被许多其他团队共享,通常导致测试数据过时。 - hidro
谢谢。我咨询了其他几位开发人员,得到了类似的反馈,将把这个答案标记为解决方案。 - zerodot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接