目录:
我们优先考虑面向服务的体系结构原则 逆 。这意味着我们拥有小型,可维护的组件,并且责任明确。它们通过Representational State Transfer或REST,API(大多数)相互通信。
这提供了灵活性,除了一个重要方面:测试之外我们也很好。测试时,应避免:
- 依赖于在同一台机器上运行的外部服务。
- 慢慢的测试。
由于应用程序本身依赖于外部服务,因此为这些依赖项制定测试策略至关重要。
我们最近开始使用Bypass,我将解释我们是如何到达那里的,特别是我们如何使用它。
过去
模拟方法并返回一些示例数据,如下所示:
那是(我相信仍然是)Ruby / Rails世界中的“前进之路”。不幸的是,这会助长不良行为,正如JoséValim在这里所解释的那样。
然后我们开始使用ExVCR,这是一个很棒的库,但是它具有类似于模拟/存根的缺点:它鼓励懒惰并且不会促成对定义良好的API至关重要的关注点的分离。 ExVCR使人们能够“记录”和“回放”真实数据。它很容易集成(包括测试中的几行,其他一切都得到了处理)。但理想情况下,您必须考虑测试中的外部依赖性,而不是将它们抽象出来。当端点行为应该以最小的开销进行测试时,它可能仍然是一个可行的选择(我们使用它来测试对Amazon的AWS服务(如S3)的调用)。
输入适配器
适配器工作得很好,促进了有关API合同和明确定义的通信边界的审议。我们仍然使用这种方法,特别是当适配器更复杂时(如JSON-RPC套接字)。
这是适配器的外观:
但是对于简单的HTTP端点,适配器似乎需要做很多工作并且有一个主要缺点:它们将测试方程式中的库消耗掉。如果HTTP或JSON库中的任何内容发生更改,则测试将无法捕获它。这种方法未经测试的生产关键代码量是不可接受的。
现在和未来
绕过允许我们在模拟我们使用的外部服务的测试中启动一个非常简单的Web服务器。
现在,我们可以测试整个堆栈,包括HTTP库,JSON编码/解码库和身份验证机制。旁路自述文件写得很好,所以我将节省实现细节。但是,我们会稍微改变我们使用它的方式,以保持测试的简洁性和可读性:
首先,我们有时希望在测试作为完整集成套件运行时调用Facebook。我们不定期地这样做,以确保Facebook API仍然符合我们的期望。添加
- 包括整合
至
混合测试
不模拟API,而是调用外部服务(第5,7行)。
当我们模拟对外部服务的请求时,我们是明确的,因此使用Bypass的每个测试都必须具有
@tag facebook_bypass
(第7行)。
最后,
handle_fb
正在调用函数(第30-39行)(假设为
request_path
火柴)。我喜欢在函数头中进行匹配,因为它明确了我们要响应的路径,并允许我们为不同的路径定义不同的函数。
所以Bypass仅在标记为的测试上运行
@tag:绕道
当我们没有运行我们的集成套件时我们在设置Bypass时要做的另一件事是允许标签传递页面ID(第8,20行)。所以这里是一个使用Bypass的测试如何看待它的所有荣耀:
如你所见,
facebook_bypass
tag明确表示我们正在模拟API(除非我们处于集成模式)。它允许我们将信息传递给模拟API,并且很容易为不同的测试重用相同的Bypass配置。
我希望这可以帮助您测试外部API。如果您有任何其他问题,可以在Twitter上找到我(见下文)。