SSO 应用程序的集成测试是一个更普遍问题的特例:测试分布式应用程序。这是一个难题,似乎没有灵丹妙药。有多种方法可以组合一组不同的服务器或服务并将它们作为一个整体进行测试。两个极端是
a) 测试整个系统的一个实例。那时您不需要任何模拟或存根,但您需要对整个堆栈进行完整、成熟的设置。这包括涉及的每个服务器的运行实例。对于每个测试,设置整个应用程序堆栈,并测试整个堆栈,即测试整个分布式系统,包括所有涉及的组件,这通常是困难的。整个事情只有在每个组件和所有连接都运行良好的情况下才有效。
b) 为每个组件编写一个集成测试,将其视为一个黑盒,并通过 mocks 和 stubs 覆盖缺失的连接。在实践中,这种方法更常见于单元测试,为每个 MVC 层编写测试:模型、视图和控制器(视图和控制器通常一起)。
在这两种情况下,您都没有考虑断开的连接。原则上,必须检查每个外部服务器/服务的以下可能性
- 下来了
- 起床并且表现良好
- 起来并且回复错误
- 已启动,但您发送的数据错误
基本上,分布式应用程序的测试是困难的。这就是分布式应用程序难以开发的原因之一。分布式应用程序拥有的部件和服务器越多,设置许多成熟的环境(如生产、登台、测试和开发)就越困难。系统越大,集成测试就越困难。在实践中,使用第一种方法并创建整个应用程序的小而完整的版本。一个典型的简单设置是 App Server + DB Server + Search Server。在您的开发机器上,您将拥有完整系统的两个不同版本:
- 具有多个数据库的一台 DB Server(开发和测试)
- 一台具有多个索引的搜索服务器(开发和测试)
用于搜索服务器的通用 Ruby 插件(Thinking Sphinx for Sphinx 或 Sunspot for Solr)支持黄瓜和集成测试。他们为测试的某些部分“打开”搜索服务器。对于不使用搜索服务器的代码,它们会“存根”服务器或模拟连接以避免不必要的索引。
对于 RSpec 测试,可以将身份验证方法存根,例如,对于控制器测试,通过
before :each do
@current_user = Factory(:user)
controller.stub!(:current_user).and_return(@current_user)
controller.stub!(:logged_in?).and_return(:true)
end
它也适用于帮助程序和视图测试,但不适用于 RSpec 请求或集成测试。
对于黄瓜测试,可以通过用存根替换到搜索服务器的连接来存根搜索服务器(对于 Sunspot 和 Solr,这可以通过替换封装到 Solr 的连接的 Sunspot.session来完成)。
这一切听起来都不错,不幸的是,将这个解决方案转移到 SSO 服务器有点困难。典型的最小设置是 App Server + DB Server + SSO Server。完整的集成测试意味着我们必须设置一个具有多个用户数据存储(开发和测试)的 SSO 服务器。设置 SSO Server 已经够难的了,设置具有多个用户数据存储的 SSO Server 可能不是一个好主意。
该问题的一种可能解决方案可能是Fakeweb方向的某个地方。FakeWeb 是由 Blaine Cook 编写的用于伪造 Web 请求的 Ruby 库。它使您可以将测试环境与实时服务分离。不幸的是,伪造 SSO 服务器的响应有点困难。
我最终使用的另一个可能的解决方案是使用假登录,即添加可以在集成测试中调用的假登录方法。这种假登录是一种仅在测试期间添加的动态方法(通过猴子补丁的形式)。这有点混乱,但似乎有效。