ruby-on-rails 为什么在水豚测试用户注销后任何重定向?

zour9fqk  于 2023-06-25  发布在  Ruby
关注(0)|答案(3)|浏览(169)

我试图测试用户使用js: true编辑问题的功能,但失败了,因为用户在测试期间没有登录(即使应该有用户会话)。
我使用Devise进行身份验证。

feature 'Authenticated User can edit own questions' do
  given(:user) { create(:user) }
  given(:another_user) { create(:user) }
  given!(:question) { create(:question, user:) }
  given!(:another_question) { create(:question, user: another_user) }

  describe 'Authenticated user', js: true do
    background { sign_in user }  ### Here I am signing in

    scenario 'can edit the question' do
      visit question_path(question) 
      
      ### Here save_and_open_page shows that no active session

      within "#question_#{question.id}" do ### Finds turbo frame tag #question_{id}
        click_on 'Edit'
        fill_in 'Body', with: 'Question is edited.'
        click_on 'Save'

        expect(page).to_not have_content question.body
        expect(page).to have_content 'Question is edited.'
        expect(page).to_not have_selector 'textarea'
      end

      expect(page).to have_content 'Question is edited.'
    end
  end
end

这是我用于登录的功能助手:

def sign_in(user)
    visit new_user_session_path
    within 'form#new_user' do
      fill_in 'Email', with: user.email
      fill_in 'Password', with: user.password
      click_on 'Log in'
    end
end

如果我在不使用js: true的情况下进行测试,测试工作,并且用户会话不会在测试期间的每次重定向后终止。
我使用Capybara.javascript_driver = :selenium_chrome_headless作为js驱动程序。

2uluyalo

2uluyalo1#

这里公认的答案可能解决了这个问题,但它是一个糟糕的解决方案。“解决方案”取决于测试硬件的运行速度,因此当您迁移到云测试基础设施时,或者当您的本地机器负载很重时,可能会出现问题。该问题的根本原因是测试异步运行,需要检查页中的可见项以进行同步。在测试中,您调用'sign_in',它会填写登录页面并单击“Log In”按钮,但是没有什么等待登录的内容。因此,测试继续,并调用visit ...更改页面,取消浏览器提交,在登录完成和会话cookie返回之前。由于浏览器还没有会话cookie,因此用户在新页面上没有被验证。sleep(1)通过尝试给登录时间来“修复”这个问题。在某些情况下,1秒将等待太长时间(浪费时间),而在其他情况下可能不够(片状测试)。更好的解决方案是检查页面上的更改,这表明登录已经完成

def sign_in(user)
    visit new_user_session_path
    within 'form#new_user' do
      fill_in 'Email', with: user.email
      fill_in 'Password', with: user.password
      click_on 'Log in'
    end
    expect(page).to have_text('Login Succeeded') # text shown on page that indicates a login has finished - or .have_css('#logged_in_menu'), etc
end

总结:不要将sleep添加到测试中,检查页面中的更改,这些更改表明可以安全地继续前进

j8ag8udp

j8ag8udp2#

实际上,您不需要每次都以这种方式登录,因为它会稍微减慢您的测试速度。我建议使用方法login_as

login_as user

如果此方法不可用,请尝试在测试中包含此帮助程序(设备控制器测试):

include Devise::Test::IntegrationHelpers

另外,我建议在这里加上感叹号

given!(:user) { create(:user) }

在运行'background'之前确保用户存在

ejk8hzay

ejk8hzay3#

在我将sleep(1)行添加到helper后,所有测试都通过了:

def sign_in(user)
    visit new_user_session_path
    within 'form#new_user' do
      fill_in 'Email', with: user.email
      fill_in 'Password', with: user.password
      click_on 'Log in'
    end
    sleep(1)
end

相关问题