0

我在使用 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 OS,- Firefox 17.0.1 - IE 8.0.7601.17514 和 IEDriverServer_x64_2.26.2 - Chrome 23.0.1271.97 m 和 chromedriver_win_23.0.1240.0, - Ruby 1.9.3p125, - watir-webdriver (0.6.1), - 硒网络驱动程序(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)
4

1 回答 1

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? ,就像您在代码中所做的那样)。

于 2013-01-10T21:12:37.700 回答