在我编写的应用程序中,我创建,更新和删除'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。有没有人知道为什么?
最好的,谢谢, 岸堤
答案 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'