Ruby on Rails - 用Capybara进行RSpec Javascript测试(RoR新手)

时间:2013-04-27 10:41:24

标签: ruby-on-rails rspec capybara capybara-webkit

Ruby,Rails和TDD的新手。我正在使用RSpec与Capybara和Capybara webkit。

尝试测试页面上是否存在div元素。

测试代码:

require 'spec_helper'
describe "Login module" do

    before do 
        visit root_path
    end

    it "should have a module container with id mLogin" do
        page.should have_css('div#mLogin')
    end

    it "should have a module container with id mLogin", :js => true do
        page.evaluate_script('$("div#mLogin").attr("id")').should eq "mLogin"
    end

end

第一次测试通过但第二次测试失败了:

Login module should have a module container with id mLogin
     Failure/Error: page.evaluate_script('$("div#mLogin").attr("id")').should eq "mLogin"

       expected: "mLogin"
            got: nil

在浏览器开发工具中使用JS并获取“mLogin”而不是nil。

有什么想法吗?感谢。

2 个答案:

答案 0 :(得分:0)

find('div#mLogin')[:id].should eq 'mLogin'

请参阅doc:

#evaluate_script
Evaluate the given JavaScript and return the result. Be careful when using this with scripts that return complex objects, such as jQuery statements. execute_script might be a better alternative.
到目前为止,

evaluate_script总是返回nil。

无论如何,你的第二次测试似乎是在测试水豚是否有效,因为你的第一次测试就足够了。

答案 1 :(得分:0)

一个可能的问题是have_css匹配器支持Capybara的同步功能。如果没有立即找到选择器,它将等待并重试,直到找到它或超时为止。

http://rubydoc.info/github/jnicklas/capybara#Asynchronous_JavaScript__Ajax_and_friends_

上有关于此的更多文档

另一方面,evaluate_script立即运行。由于这是您在访问页面后首先执行的操作,因此存在竞争条件:在页面加载完成之前,它可能会执行此脚本。

您可以尝试在页面上找到一个元素,直到

或者,您可以在调用synchronize时将呼叫包裹起来以显式重试,但通常不建议这样做。对于这样的情况,使用Capybara的内置匹配器会更好。只有当没有内置的方法来完成你需要做的事情时,evaluate_script方法才应该作为最后的手段使用,你需要非常小心以避免竞争条件。