如何在 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 中设置会话值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django 中设置会话永不过期

如何在 web.config 中设置会话超时

如何在 ktor 中设置会话超时?

如何在 django 中设置和获取会话变量?

如何在 Laravel 中设置会话超时?

在控制器中设置Laravel会话生存期