使用Webrat进行测试时如何处理cookie?

我正在使用Webrat为基于Sinatra的应用程序编写Cucumber测试。 对于某些测试,我需要实现一个类似的场景

Given I am logged in as admin When I am visiting "/" Then I should see "Settings" 

我定义了这样的步骤:

 Given /^I am logged in as "(.+)"$/ do |user| visit "/login" fill_in "login", :with => user fill_in "password", :with => "123456" click_button "Login" end When /^I am viewing "(.+)"$/ do |url| visit(url) end Then /^I should see "(.+)"$/ do |text| response_body.should =~ /#{text}/ end 

成功时,会创建一个cookie

 response.set_cookie(cookie_name, coockie_value) 

然后在用户尝试通过帮助程序方法访问管理页面时在视图中进行validation:

 def logged_in? request.cookies[cookie_name] == cookie_value end 

看起来Webrat不存储cookie。 测试不报告任何错误,但“logged_in?” 在视图中总是错误的,就像cookie没有保存一样。

难道我做错了什么? 如果这只是Webrat的工作方式,那么最好的解决方法是什么?

真正的问题是Sinatra在测试环境中处理会话的方式。 搜索Google小组进行讨论,但真正的解决方案是简单地使用:

 use Rack::Session::Cookie 

不是

 enable :sessions 

使用Selenium很不错,但它作为OP问题的解决方案是过度的。

解决方法是使用带有Selenium后端的Webrat。 它在一个单独的Firefox窗口中运行所有测试,因此cookie或javascript不是问题。 缺点是运行Firefox并执行所有实际点击,渲染等所需的额外时间和资源。

你可以让你的“给我/我登录”步骤hack logged_in?

 Given /^I am logged in as "(.+)"$/ do |user| visit "/login" fill_in "login", :with => user fill_in "password", :with => "123456" click_button "Login" ApplicationController.class_eval <<-EOE def current_user @current_user ||= User.find_by_name(#{EOE}) end end EOE end 

有两个缺点:

  1. 将视图级别和控制器级别的问题混合在一起真是太苛刻了。
  2. 模拟“注销”会很困难