【问题标题】:Rails - Capybara - reset_sessions isnt working with Google OAuthRails - Capybara - reset_sessions 不适用于 Google OAuth
【发布时间】:2018-04-11 20:17:26
【问题描述】:

我的应用要求用户通过 Google OAuth 登录。当我运行多个测试时,Google OAuth 不会重置会话,因此在第一次测试之后,所有后续测试都将访问我们的站点并且已经登录。

我最近发现了这个问题并遇到了 3 个场景(我已经包含了基本示例)。每个场景首先让用户导航到我们的登录页面,单击将用户发送到 Google OAuth 的按钮,登录然后验证 url。

第一个场景只是导航到我们的网站并登录。结果是第一个测试通过了,但所有后续测试都预计会到达 Google OAuth 登录页面,但已登录:

feature 'All Films Page' do
  context 'user is logged in as an Admin role' do
    before(:each) do
        Capybara.reset_sessions!

        visit('/')
      app.google_signin.sign_into_app('admin')
    end

    scenario '1' do
      expect(page).to have_current_path('/films')
    end

    scenario '2' do
      expect(page).to have_current_path('/films')
    end
  end
end

第二种情况添加了“reset_sessions!”用于谷歌 OAuth。这样做的结果是,在第一次测试后,用户到达了 Google OAuth,但之前的用户是一个可选选项,因为之前已登录。

feature 'All Films Page' do
  context 'user is logged in as an Admin role' do
    before(:each) do
      visit('https://accounts.google.com')
      Capybara.reset_sessions!
      visit('/')

      app.google_signin.sign_into_app('admin')
    end

    scenario '1', :integration do
      expect(page).to have_current_path('/films')
    end

    scenario '2', :integration do
      expect(page).to have_current_path('/films')
    end
  end
end

第三个场景添加了两个“reset_sessions!”用于谷歌 OAuth。这将创建每个测试的预期结果,并重置其会话。

feature 'All Films Page' do
  context 'user is logged in as an Admin role' do
    before(:each) do
      visit('https://accounts.google.com')
      Capybara.reset_sessions!
      visit('/')

      visit('https://accounts.google.com')
      Capybara.reset_sessions!
      visit('/')

      app.google_signin.sign_into_app('admin')
    end

    scenario '1', :integration do
      expect(page).to have_current_path('/films')
    end

    scenario '2', :integration do
      expect(page).to have_current_path('/films')
    end
  end
end

【问题讨论】:

    标签: ruby-on-rails oauth rspec capybara


    【解决方案1】:

    对于测试,您应该模拟或存根外部行为。让我们考虑一个计费服务,您需要在其中测试信用卡支付的行为……您不想在运行测试时支付真钱。还有一些方法,人们完全模拟数据库行为并且只使用单元测试进行测试,因为它们更快,并且他们说数据库层不是他们想要测试的,它是他们自己的应用程序。 对于您的示例,这是一个集成测试,您应该查看人们使用 rspec 对 oauth 提供者的外部调用存根的示例。为什么?因为您想测试您的应用程序内部行为,而不是 google 的行为...您使用的是特殊版本的 google oauth,因此您可以将其视为您的应用程序与外部提供商之间的合同。解释我在说什么的一页是http://www.jessespevack.com/blog/2016/10/16/how-to-test-drive-omniauth-google-oauth2-for-your-rails-app

    【讨论】:

      【解决方案2】:

      这是因为 Capybara 只能清除它所在域的 cookie - 因此您需要清除每个域上的 cookie,它们保存在其中会影响您的测试。假设您使用的是 selenium 驱动程序,因为您没有提及其他情况,这应该可以通过访问每个域并执行

      page.driver.browser.manage.delete_all_cookies
      

      而不是需要多次调用reset_session!。话虽如此,您是否有充分的理由真正需要真正使用 Google 登录,而不是将您正在使用的任何身份验证库置于测试模式?例如omniauth - https://github.com/omniauth/omniauth/wiki/Integration-Testing

      【讨论】:

      • 嗨,Thomas,我有一个关于omniauth 的问题:如果针对暂存环境(和url)进行测试,我是否需要访问暂存数据库才能使用omniauth? (在本地测试时,我可以访问我的测试数据库)
      • @Justin 如果您正在针对暂存环境进行测试(该应用程序未由 Capybara 运行/管理),那么您不能使用 omniauth 测试模式并且需要登录通过真正的谷歌(以及从多个域中清除 cookie),或者您需要使用像 puffing-billy 这样的可编程代理来模拟来自谷歌的响应。
      猜你喜欢
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      • 2015-11-07
      • 1970-01-01
      • 2021-06-10
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      相关资源
      最近更新 更多