为什么这些测试在同时运行时会失败,但每个都单独通过?

时间:2017-01-10 00:45:37

标签: ruby-on-rails rspec devise

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

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

当每个规范单独运行时,它们都会通过。当所有规格一起运行时,它们会失败,因为缺少预期的内容。使用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认为用户没有登录,但每个规格都是单独传递的?

2 个答案:

答案 0 :(得分:0)

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

经过多次搜索,我最终找到login_as may not work with Poltergeist when js is enabled on your test scenarios.

this small mention

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

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

我尝试使用Transactional Capybara宝石,但这似乎与Poltergeist不太合作。

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

此解决方案似乎正在运行。它增加了一点开销,所以我只用它来测试JS。

答案 1 :(得分:0)

如果您使用的是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