如何在 Capybara 中设置会话值?
Posted
技术标签:
【中文标题】如何在 Capybara 中设置会话值?【英文标题】:How do I set up a session value in Capybara? 【发布时间】:2012-01-22 17:28:07 【问题描述】:我正在为 Shopify 开发一个应用,我想做集成测试。
我需要能够在会话变量中存储一些值,以便进行身份验证。
我该怎么做?
我使用 Capybara 和 Capybara-webkit。
【问题讨论】:
在集成测试中,您应该从登录表单中记录用户。 那行不通。关键问题是我使用的是外部身份验证系统:Shopify。因此 Shopify 配置为将成功登录返回到特定 URL。看到问题了吗?该 URL 不能是 localhost。这就是为什么我需要伪造登录过程,即使我正在进行集成测试 如何在 shopify 应用中使用相同的黄瓜? 【参考方案1】:接受的答案建议rack_session_access。它通过插入中间件控制器来编辑和更新会话状态,然后让水豚访问该页面并提交带有会话数据的表单。非常巧妙!但如果您使用 Warden(直接或通过 Devise),则没有必要。
Warden 有一个钩子on_next_request 可以访问warden 机制,可以用来直接设置会话密钥。我把它放在一起以将其捆绑在 rspec 中:
创建spec/support/inject_session.rb
:
module InjectSession
include Warden::Test::Helpers
def inject_session(hash)
Warden.on_next_request do |proxy|
hash.each do |key, value|
proxy.raw_session[key] = value
end
end
end
end
在spec/spec_helper.rb
中将模块包含在功能规范中:
RSpec.configure do |config|
config.include InjectSession, :type => :feature
end
那么规范中的示例使用可能是:
inject_session :magic => 'pixie dust', :color => 'pink'
visit shopping_cart_path
page.should be_all_sparkly_and_pink # or whatever
【讨论】:
@YossiShasho 以什么方式不起作用?它似乎对我来说很好用,目前使用的是 devise 3.2.4 和warden 1.2.3 老实说,我不记得出了什么问题,但我并没有努力解决它。继续使用上面建议的rack_session_access
gem,效果很好。
我会非常喜欢这个解决方案。不幸的是没有工作所以我也切换到 rack_session_access (Ruby 2.2, Rails 4.2)
这也适用于 Rails 4.2、Devise 3.4.1 等。
你让男人变得更好!在这里工作 Devise 4.5.0 和 Rails 5.2.1。谢谢!
【参考方案2】:
刚刚找到rack_session_access gem 并作为一个魅力工作。
【讨论】:
@fguillen 如何在 shopify 应用程序中使用相同的黄瓜?【参考方案3】:正如 apneadiving 的评论所建议的那样,您应该使用 capybara “直接”填写表格。使用 Cucumber 进行的测试可能如下所示,用于填写登录表单以进行身份验证(来自 Capybara github 页面):
When /I sign in/ do
within("#session") do
fill_in 'Login', :with => 'user@example.com'
fill_in 'Password', :with => 'password'
end
click_link 'Sign in'
...
end
如果您尝试做一些不同的事情或在正常登录过程中遇到问题,this SO 问题可能会有所帮助。
【讨论】:
那行不通。关键问题是我使用的是外部身份验证系统:Shopify。因此 Shopify 配置为将成功登录返回到特定 URL。看到问题了吗?该 URL 不能是 localhost。这就是为什么我需要伪造登录过程,即使我正在进行集成测试。 @Nerian 看看是否可以使用github.com/myronmarston/vcr 将外部请求记录到本地环境中,然后您可以使用此方法。【参考方案4】:我担心我会带来坏消息,但来自 Capybara 的文档:
无法从测试中访问会话和请求,访问 反应有限。
因此您将无法按预期进行测试。
只是想:在控制器中插入一些条件语句用于测试目的是可以接受的。:
session[:foo] = User.first.id if Rails.env.test?
更好的选择是只为集成测试对控制器进行猴子补丁。
【讨论】:
这是可能的,但感觉就像代码异味 - 将测试代码注入您的生产应用程序?如果可以的话,最好重写你的测试。【参考方案5】:您可以使用 VCR 或 webmock 之类的东西来消除对外部 http 资源的调用。
【讨论】:
以上是关于如何在 Capybara 中设置会话值?的主要内容,如果未能解决你的问题,请参考以下文章