水豚不等待ajax完成 [英] Capybara is not waiting for ajax to finish
问题描述
我正在开发一个包含EmberJS前端的应用程序,该前端通过REST与Rails服务器通信。在我的应用程序中,通过向导创建了一个作业,因此我想测试是否创建了该作业,这是我的测试。
功能处理第三步,:js =>真的做
背景吗
to_step_2
to_step_3
结束
场景'正在创建工作',js:真的要做
在'#login'中
fill_in'Email',with:@ customer.email
fill_in'Password',with:@ customer.password
click_button'Login'
end
期望{click_link'Create job'} .tochange(Job,:count).by(1)
end
end
因此,当用户填写完所有内容后,最后他们单击创建作业,就像我的测试所描述的那样。
1),当我手动执行此操作时,此方法工作正常。三个创建作业
$ p $中p>
失败/错误:期望{click_link'Create job'} .to change(Job,:count).by(1)
计数应已更改为1,但已更改为0
#./spec/features/creating_a_new_job_spec.rb:103:in在< top(必填)>'
现在,如果我看一下测试日志,我可以看到,在插入我的工作之前,水豚会进行计数
在36ms内完成了200 OK(查看:6.0ms | ActiveRecord:11.2ms)
在2013-12-08 14开始为127.0.0.1启动POST / api / jobs: 15:00 +0100
由Api :: JobsController#create处理为JSON
参数:{ job => { description =>这是我对服务的测试描述喜欢接收。, zip => 2400, available_from => 2013年12月12日, available_next => false, customer_id => 1,服务 e_id => 1, service_field_id => 1}}
不允许的参数:zip
(11.3ms)从 jobs中选择COUNT(*)
( 1.2ms)开始
SQL(2.5ms)插入作业( available_from, available_next, created_at, customer_id, description, service_field_id, service_id, updated_at )值($ 1,$ 2,$ 3,$ 4,$ 5,$ 6,$ 7,$ 8)返回 id [[[ available_from,星期二,2013年12月24日00:00:00 UTC +00:00],[ available_next ,false],[ created_at,周日,2013年12月8日13:15:00 UTC +00:00],[ customer_id,1],[ description,这是我对服务的测试描述喜欢接收。] [[ service_field_id,1],[ service_id,0],[ updated_at,Sun,2013年12月8日13:15:00 UTC +00:00]]
( 0.5毫秒)提交
我如何强迫水豚稍稍起风?
解决方案正如您所说,主要问题是水豚没有等。但是主要原因是测试没有使用一致的样式。
如果使用Capybara,则测试的行为就像真实用户一样,您应该期望一些UI更改而不是数据库更改,因为真实用户看不到db中会发生什么
在此测试中,db断言立即执行,比浏览器驱动程序向服务器发送数据的速度更快,因此数据为零。
要修复,
删除
在
内。这似乎并不重要。如果我没有记错的话,期望最好不要采取不同的行动。出于安全考虑,也可以这样做。
添加用户界面期望值。然后水豚将等到效果出现。
所以,
s场景'正在创建工作',js:true
fill_in'Email',带有:@ customer.email
fill_in'Password',带有:@customer .password
click_button'登录'
#假设您的页面在登录
后将显示用户名Expect(page).to have_content(@ customer.name)
end
如果您真的想测试数据库更改,则可以在UI期望之后添加该期望,但我不建议
I'm working on a application which consist of a EmberJS frontend, which talk to a Rails server via REST. In my application goes through a wizard to create a job, so i would like to test if that job is created, this is my test.
feature 'Processing step three', :js => true do background do to_step_2 to_step_3 end scenario 'Creating job', js: true do within '#login' do fill_in 'Email', with: @customer.email fill_in 'Password', with: @customer.password click_button 'Login' end expect { click_link 'Create job' }.to change(Job, :count).by(1) end end
So when the user has filled in everything, lastly they click on create job, just like my test describes. This works fine when i do it manually, but when i run my spec i get.
1) Creating a new job Processing step three Creating job Failure/Error: expect { click_link 'Create job' }.to change(Job, :count).by(1) count should have been changed by 1, but was changed by 0 # ./spec/features/creating_a_new_job_spec.rb:103:in `block (3 levels) in <top (required)>'
Now if i look at my test log i can see, that capybara runs the count, before my job is inserted
Completed 200 OK in 36ms (Views: 6.0ms | ActiveRecord: 11.2ms) Started POST "/api/jobs" for 127.0.0.1 at 2013-12-08 14:15:00 +0100 Processing by Api::JobsController#create as JSON Parameters: {"job"=>{"description"=>"This is a test description of the service i would like to receive.", "zip"=>"2400", "available_from"=>"24 - 12 - 2013", "available_next"=>false, "customer_id"=>"1", "service_id"=>"1", "service_field_id"=>"1"}} Unpermitted parameters: zip (11.3ms) SELECT COUNT(*) FROM "jobs" (1.2ms) BEGIN SQL (2.5ms) INSERT INTO "jobs" ("available_from", "available_next", "created_at", "customer_id", "description", "service_field_id", "service_id", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["available_from", Tue, 24 Dec 2013 00:00:00 UTC +00:00], ["available_next", false], ["created_at", Sun, 08 Dec 2013 13:15:00 UTC +00:00], ["customer_id", 1], ["description", "This is a test description of the service i would like to receive."], ["service_field_id", 1], ["service_id", 0], ["updated_at", Sun, 08 Dec 2013 13:15:00 UTC +00:00]] (0.5ms) COMMIT
How do i force Capybara to hold the sails a bit?
解决方案The main problem, as you said, it's Capybara didn't wait. But the main reason is the test doesn't use a consistent style.
If using Capybara, the test acts like a real user, and you should expect some UI change instead of database change, for real user can't see what happens in db.
In this test, the db assertion is executed right away, even faster than the browser driver sending data to server, so the data is nil.
To fix,
Remove the
within
block at first. This seems unimportant. If I remembered correctly, the expectation should better not in different block of the action. So do it for safety.Add UI expectation. Then Capybara will wait until the effect appears.
So,
scenario 'Creating job', js: true do fill_in 'Email', with: @customer.email fill_in 'Password', with: @customer.password click_button 'Login' # Assume your page will show user name after signing in expect(page).to have_content(@customer.name) end
If you really want to test db change, you can add that expectation after UI expectation, but I don't recommend that.
这篇关于水豚不等待ajax完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!