单点登录页面的集成测试

0x4*_*672 4 integration-testing opensso cucumber single-sign-on capybara

如何在集成测试期间使用单点登录(SSO)登录测试页面(例如使用caybara或cucumber)?对于正常登录,您将编写一个方法来访问登录页面,填写表单并提交.如果登录表单来自Shibboleth或OpenAM/OpenSSO等外部SSO服务器,则这有点困难.如何为受SSO保护的页面编写集成测试?

类似的问题是使用单独的搜索服务器(Solr或Sphinx)进行集成测试.您可能会通过使用某种形式的模拟或存根来解决它.有人能给出一个很好的例子,如何模拟或存根黄瓜或水豚的SSO?如果这太难了,那么搜索服务器的类似示例也会有所帮助.

0x4*_*672 7

SSO应用程序的集成测试是一个更普遍的问题的特例:测试分布式应用程序.这是一个难题,似乎没有一个神奇的子弹.有多种方法可以组合一组不同的服务器或服务,并将它们作为一个整体进行测试.两个极端是

a)测试整个系统的实例.您不需要任何模拟或存根,但您需要完整,完整的整个堆栈设置.这包括所涉及的每个服务器的运行实例.对于每个测试,设置整个应用程序堆栈,并测试整个堆栈,即整个分布式系统测试所涉及的所有组件,这一般是困难的.只有当每个组件和所有连接都运行良好时,这一切才有效.

b)为每个组件编写集成测试,将其视为黑盒子,并通过模拟和存根覆盖缺少的连接.实际上,这种方法对于单元测试更为常见,一种是为每个MVC层编写测试:模型,视图和控制器(视图和控制器通常在一起).

在这两种情况下,您都没有考虑过断连接.原则上,必须检查每个外部服务器/服务以下可能性

  • 落了下来
  • 起来并表现得很好
  • 是,并且回复错误
  • 是,但你发错了数据

基本上,分布式应用程序的测试很困难.这就是分布式应用程序难以开发的原因之一.分布式应用程序拥有的部件和服务器越多,设置许多成熟环境(如生产,升级,测试和开发)就越困难.系统越大,集成测试就越困难.在实践中,人们使用第一种方法并创建整个应用程序的小而完整的版本.典型的简单设置是App Server + DB Server + Search Server.在您的开发机器上,您将拥有一个完整系统的两个不同版本:

  • 一个带有多个数据库的DB服务器(开发和测试)
  • 一个具有多个索引的搜索服务器(开发和测试)

搜索服务器的常见Ruby插件(适用于Sphinx的Thinking Sphinx或适用于Solr的Sunspot)支持黄瓜和集成测试.他们为测试的某些部分"打开"搜索服务器.对于不使用搜索服务器的代码,它们"存根"服务器或模拟连接以避免不必要的索引.

对于RSpec测试,可以存根认证方法,例如对于控制器测试

  before :each do
    @current_user = Factory(:user)
    controller.stub!(:current_user).and_return(@current_user)
    controller.stub!(:logged_in?).and_return(:true)
  end
Run Code Online (Sandbox Code Playgroud)

它也适用于辅助和视图测试,但不适用于RSpec请求或集成测试.

对于黄瓜测试,可以通过用存根替换与搜索服务器的连接来截断搜索服务器(对于Sunspot和Solr,这可以通过替换封装与Solr的连接的Sunspot.session来完成).

这听起来不错,遗憾的是,为SSO服务器传输此解决方案有点困难.典型的最小设置是App Server + DB Server + SSO Server.完整的集成测试意味着我们必须设置一个具有多个用户数据存储的SSO服务器(开发和测试).设置SSO服务器已经足够困难,设置具有多个用户数据存储的SSO服务器可能不是一个好主意.

问题的一个可能的解决方案可能是在Fakeweb方向的某个地方.FakeWeb是由Blaine Cook编写的用于伪造Web请求的Ruby库.它允许您将测试环境与实时服务分离.遗憾的是,伪造SSO服务器的响应有点困难.

我最终使用的另一个可能的解决方案是使用伪登录,即添加可在集成测试中调用的伪登录方法.这个假登录是一种动态方法,仅在测试期间添加(通过猴子修补的形式).这有点乱,但似乎有效.