如何提高Watir element.present的性能?方法?

时间:2013-01-10 17:33:53

标签: watir watir-webdriver

我使用Watir体验了使用Ruby脚本的IMO高延迟。这是问题描述:我正在测试基于AJAX的应用程序,我想避免使用sleep来确保页面被加载:

class Page
  attr_accessor :expected_elements

  def loaded?
    # code to make sure AJAX page is loaded
  end
end

所以不要这样:

def loaded?
  # static delay sufficient to get page loaded
  sleep(MAX_PAGE_LOAD_TIME)
  true
end

我想要这样的东西:

def loaded?
  Watir::Wait.until(MAX_PAGE_LOAD_TIME) do
    expected_elements.all? do |element|
      element.present?
    end
  end
end

问题是块的评估花费的时间太长。我检查存在的元素越多,此延迟越高。我经历了一次迭代的大致延迟:

Firefox -> 130ms
IE -> 615ms
Chrome -> 115 ms

因此要检查是否存在N个元素,我得到N次相应的延迟...结果是,尽管MAX_PAGE_LOAD_TIME到期,但是由于块评估尚未完成,因此不会抛出Watir :: Wait :: TimeoutError ...所以我最终处于这样的情况:元素存在的检查引入了比静态延迟更高的延迟,这足以使页面加载。我试图通过xpath定位元素来提高性能,但性能增益并不显着。 我究竟做错了什么?有没有办法加快现在的执行时间?方法??这些延迟是否符合您的经验 - 或者它们是否很高?

我检查了问题是否可能在浏览器 - 服务器通信中,但这里的延迟非常低..我的服务器响应时间差为100毫秒,包括后端数据库请求。当然,基于此响应渲染页面需要一些时间,但肯定不需要几秒钟。

我的配置: - Win7操作系统, - Firefox 17.0.1 - 带有IEDriverServer_x64_2.26.2的IE 8.0.7601.17514 - Chrome 23.0.1271.97米,带chromedriver_win_23.0.1240.0, - Ruby 1.9.3p125, - watir-webdriver(0.6.1), - selenium-webdriver(2.27.2)

感谢您的帮助!

根据讨论,我发布了基准代码示例:

Benchmark.bm do |x|
  x.report("text") do
    b.span(:text => "Search").present?
  end
end
Benchmark.bm do |x|
  x.report("xpath") do
    b.span(:xpath => "/html/body/div/div/div[2]/div[2]/div/div/div/div/div/div/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/div/div/div/div/div/div/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/div/div/div/div/div/span/span").present?
  end
end

        user     system      total        real
text   0.000000   0.000000   0.000000 (  0.140405)
xpath  0.000000   0.000000   0.000000 (  0.120005)

其他基准测试结果:

container_xpath = "/html/body/div/div/div[2]/div[2]/div/div/div/div/div/div/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div[2]/div/div/div/div[2]/div/div/div"
Benchmark.bm do |x|
  x.report("cntnr") do
    @c = b.div(:xpath => container_xpath)
    @c.present?
  end
end
Benchmark.bm do |x|
  x.report("lb1") do
    @c.div(:xpath => "div[1]/div/div").present?
    #@c.div(:text => "Company:").present?
  end
end
Benchmark.bm do |x|
  x.report("lb2") do
    @c.div(:xpath => "div[3]/div/div").present?
    #@c.div(:text => "Contact person:").present?
  end
end
Benchmark.bm do |x|
  x.report("lb3") do
    @c.div(:xpath => "div[5]/div/div").present?
    #@c.div(:text => "Address:").present?
  end
end

结果是:

Results for container reference and relative xpath:
       user     system      total        real
cntnr  0.000000   0.000000   0.000000 (  0.156007)
lb1    0.000000   0.000000   0.000000 (  0.374417)
lb2    0.000000   0.000000   0.000000 (  0.358816)
lb3    0.000000   0.000000   0.000000 (  0.358816)

Results for container reference and div's text:
       user     system      total        real
cntnr  0.000000   0.000000   0.000000 (  0.140402)
lb1    0.000000   0.000000   0.000000 (  0.358807)
lb2    0.000000   0.000000   0.000000 (  0.358807)
lb3    0.000000   0.000000   0.000000 (  0.374407)

当使用绝对xpath时:

container_xpath = "/html/body/div/div/div[2]/div[2]/div/div/div/div/div/div/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div[2]/div/div/div/div[2]/div/div/div"
Benchmark.bm do |x|
  x.report("cntnr") do
    @c = b.div(:xpath => container_xpath)
    @c.present?
  end
end

lb1_xpath = container_xpath + "/div[1]/div/div"
Benchmark.bm do |x|
  x.report("lb1_x") do
    b.div(:xpath => lb1_xpath).present?
  end
end

lb2_xpath = container_xpath + "/div[3]/div/div"
Benchmark.bm do |x|
  x.report("lb2_x") do
    b.div(:xpath => lb2_xpath).present?
  end
end

lb3_xpath = container_xpath + "/div[5]/div/div"
Benchmark.bm do |x|
  x.report("lb3_x") do
    b.div(:xpath => lb3_xpath).present?
  end
end

结果是:

       user     system      total        real
cntnr  0.000000   0.000000   0.000000 (  0.140404)
lb1_x  0.000000   0.000000   0.000000 (  0.124804)
lb2_x  0.000000   0.000000   0.000000 (  0.156005)
lb3_x  0.000000   0.000000   0.000000 (  0.140405)

1 个答案:

答案 0 :(得分:1)

好的,这个答案假定您的网站正在使用jquery。如果不是,你将不得不找出正在使用的库并相应地修改方法......

编写一个等待Ajax调用完成的方法......

def wait_for_ajax(timeout = 10)
  timeout.times do
    return true if browser.execute_script('return jQuery.active').to_i == 0
    sleep(1)
  end

  raise Watir::Wait::TimeoutError, "Timeout of #{timeout} seconds exceeded on waiting for Ajax."
end

首次加载正在测试的页面时调用该方法。然后迭代你想要的元素,看看它们是否存在(如果你有一个Watir元素数组要检查,请确保你使用.each,而不是.all?就像你的代码那样)。