在水豚测试期间以任意频率发生错误

时间:2016-10-19 19:36:00

标签: ruby-on-rails ruby-on-rails-4 capybara minitest

在我编写的应用程序中,我创建,更新和删除'places'类的对象。根据用户是否登录,在索引视图中公众可以看到该位置之前,需要首先检查该位置。

我们从一开始就使用Minitest和Capybara作为我们的测试框架,因为我们的一些Capybara规格出现问题......

a)...传递而不是传递给不同的机器(特别是在我们的本地系统和Travis CI上)

b)......在本地机器的不同运行中传递而不是通过看似任意的

我不得不承认这对我来说有点奇迹,甚至更难找到错误来源。以下规范显示了这种行为:

require_relative '../../test_helper'

feature 'Review place' do
  before do
    create(:place, :reviewed)
  end

  scenario 'Do not show user edits in review index', :js do
    login
    visit '/places/1/edit'
    fill_in('place_name', with: 'USER CHANGE')
    click_on('Update Place')
    visit '/places/review_index'
    page.wont_have_content('USER CHANGE')
  end

  scenario 'Show guest edits in review index and review place', :js do
    visit '/places/1/edit'
    fill_in('place_name', with: 'GUEST CHANGE')
    validate_captcha
    click_on('Update Place')
    login
    visit '/places/review_index'
    page.must_have_content('SomeReviewedPlace')
    visit '/1/review_place'
    sleep(1)
    page.must_have_content('SomeReviewedPlace')
    page.must_have_content('GUEST CHANGE')
  end
end

require_relative '../../test_helper'

feature 'Edit place' do
  before do
    create(:place, :reviewed)
  end

  scenario 'Do valid place update as user and show in index afterwards', :js do
    login
    visit '/places/1/edit'

    fill_in('place_name', with: 'Any place')
    fill_in('place_street', with: 'Schulze-Boysen-Str.')
    fill_in('place_house_number', with: '80')
    fill_in('place_postal_code', with: '10963')
    fill_in('place_city', with: 'Berlin')
    fill_in('place_email', with: 'schnipp@schnapp.com')
    fill_in('place_homepage', with: 'http://schnapp.com')
    fill_in('place_phone', with: '03081763253')
    click_on('Update Place')
    visit '/places'

    page.must_have_content('Any place')
    page.must_have_content('10963 Berlin')
  end

  scenario 'Do valid place update as guest and show in index afterwards as to be reviewed', :js do
    visit '/places/1/edit'
    fill_in('place_name', with: 'Some changes')
    validate_captcha
    click_on('Update Place')
    visit '/places'

    page.must_have_content('Some changes')
    page.must_have_css('.glyphicon-eye-open')
  end

  scenario 'Do valid place update as guest and do not show changes within other users session', :js do
    visit '/places/1/edit'
    fill_in('place_name', with: 'SomeOtherName')
    validate_captcha
    click_on('Update Place')

    Capybara.reset_sessions!
    visit '/places'
    page.wont_have_content('SomeOtherName')
    page.must_have_content('SomeReviewedPlace')
    page.wont_have_css('.glyphicon-eye-open')
  end
end

两个测试都随意

失败
  

ActiveRecord :: RecordNotFound:找不到'id'= 1

的地方

虽然这个地方因

而必须存在
before do
  create(:place, :reviewed)
end

单独运行测试文件时,错误不会出现,只有在rake test内传递的完整链中的SOMETIMES。有没有人知道为什么?

最好的,谢谢, 岸堤

1 个答案:

答案 0 :(得分:1)

您的测试中有几个问题

第一个是在每个场景之前运行前块,并且当第二个场景运行时,创建的对象的id可能是2(除非先前的场景创建了更多的位置然后它会更高),等等。解决这个问题,您应该保存您正在创建的对象,然后使用其ID生成访问路径

before do
  @place = create(:place, :reviewed)
end

然后当你需要访问它时

visit("/places/#{@place.id}/edit") 

或使用路线助手

visit(edit_place_path(@place))  # preferred unless you're actually testing the text used for the url

第二个问题是,在访问新位置之前,您并没有等到click_on完成它所做的任何事情。使用支持JS的驱动程序时,无法保证在这些操作返回时浏览器点击/交互触发的操作已完成。您需要在访问新位置之前检查指示操作已完成的可见更改,否则新访问可以在完成之前取消触发或处理的操作。

click_on('Update Place')
page.must_have_content('Place Updated') #whatever message is displayed
visit '/places'