【问题标题】:Why do these tests fail when run simultaneously, yet each passes individually?为什么这些测试在同时运行时会失败,但每个测试都单独通过?
【发布时间】:2017-01-10 00:45:36
【问题描述】:

我遇到了非常奇怪的测试行为,登录状态处理不一致。

规范让用户登录,访问(嵌套或非嵌套)索引页面,并检查显示的内容是否正确。记录是异步获取的,但我认为这不会产生影响。

当每个规范单独运行时,它们都通过了。当所有规范一起运行时,它们会失败,因为缺少预期的内容。使用save_and_open_page 表明这是因为正在呈现登录页面,而不是预期的索引页面。

为什么当所有规范一起运行时,rspec 认为用户没有登录,但每个规范都单独通过?

测试看起来像这样

let(:user) {create :user}
let(:team) {create :team}
let(:country) {create :country}

before :each do 
  login_as( user, scope: :user )
end

describe 'unnested' do
  it 'should have the expected content', :js do 
    visit users_path
    is_expected.to have_content "some content on the page"
  end
end

describe 'nested by team' do
  it 'should have the expected content', :js do 
    visit team_users_path(team)
    is_expected.to have_content "some content on the page"
  end
end

describe 'nested by nationality' do
  it 'should have the expected content', :js do 
    visit country_users_path(country)
    is_expected.to have_content "some content on the page"
  end
end

规范都需要javascript(我不知道这是否重要)。

身份验证由Devise处理,我的rails_helper.rb包括

config.append_after(:each) do
  DatabaseCleaner.clean
  Warden.test_reset!
end

为什么当所有规范一起运行时,rspec 认为用户没有登录,但每个规范都单独通过?

【问题讨论】:

    标签: ruby-on-rails rspec devise


    【解决方案1】:

    花了很长时间才弄清楚这一点。发布此消息以防其他遇到相同问题的人有所帮助。

    经过大量搜索,我最终找到了this small mention 那个login_as may not work with Poltergeist when js is enabled on your test scenarios.

    我尝试了建议的修复方法来处理共享数据库连接。不幸的是,这导致了以下错误:

    PG::DuplicatePstatement at /session/users/signin
    ERROR:  prepared statement "a1" already exists
    

    我尝试使用 Transactional Capybara gem,但这似乎不适用于 Poltergeist。

    最终我完全放弃了login_as,而是写了一个简短的方法来访问登录页面,填写电子邮件和密码,然后以这种方式登录。

    此解决方案似乎有效。它增加了一点开销,所以我只将它用于 JS 测试。

    【讨论】:

      【解决方案2】:

      如果您使用 Capybara gem,则无需将 :js 与测试用例一起使用

      如果这有帮助,我会怎么做-

      scenario "visit with user signed in" do
        user = FactoryGirl.create(:user)
        login_as(user, :scope => :user)
        visit "/"
        expect(current_path).to eq('/')
        expect(page).to have_title "Some Random Title"
      end
      

      您可以使用功能规范登录用户的另一种方式 -

      feature 'User signs in' do
        before :each do
          @user = FactoryGirl.create(:user)
        end
      
        scenario "Signing in with correct credentials" do
          visit "/"
          fill_in "Email", with: @user.email
          fill_in "Password", with: @user.password
          click_button "Log In"
          expect(current_path).to eq("/login/useremail/verification")
          expect(page).to have_content "Signed in successfully"
        end  
      end
      

      如果您的页面是 ajax,请参考此https://robots.thoughtbot.com/automatically-wait-for-ajax-with-capybara

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-17
        • 2021-08-18
        • 1970-01-01
        • 2015-07-15
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多