我使用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)
答案 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?就像你的代码那样)。