以下是我之前固有思维中对隐式等待和显示等待区别的理解:
隐式等待需要等待整个页面加载完,才会去找整个dom树中找元素,即页面加载完后,代码块执行到需要定位的元素时,这个时候会去整个dom树中找该元素,如果在规定时间内找到了,那么立刻执行下一句代码,如果没找到,会不断的轮巡dom树,直到超过设定的等待时间。
但是当页面中的需要动态加载的内容很多时,有时候需要的元素其实早已经找到了,但还是得等这个页面加载完,才会去执行下一步,这个时候只用隐式等待就不高效了,而且有些元素不一定能找的到。
那么就轮到显示等待登场了,显示等待不会等页面加载完,它会在页面加载的同时,就开始以你设定的频率去不断的找元素,只要找到元素并且满足设定的条件,直接执行下一步,不会过多的等待,显示等待会高效很多。
所以,综上所述,在实际项目中,最佳方案是隐式等待全局控制,其他所有元素查找都尽量用显示等待,这样显示+隐式等待双保险,能极大提升脚本的稳定性和效率。
最近听了老师的课程后,发现好像有些地方是不是理解错了:
1、隐式等待是否也不需要等待整个dom树加载完才开始找元素,而是在加载页面的同时就已经开始在找元素了呢?
2、设置显示等待的原因,是因为隐式等待设置的时间是固定的,而要找的每个元素等待时间或短或长,所以用隐式还不够智能?
3、在项目中是否每个元素定位都用显示等待更好呢?
麻烦老师看到能解惑一下(不好意思,可能废话有点多)
1 个赞
那问题来了,什么时候适合用隐式等待。。这么一说,感觉所有元素定位都用显示等待就好了,速度还快,但是在实际工作项目中也遇到过不稳定的情况,不知道是什么原因(可能是隐式显示混合用了?)
本质是在最大超时时间内循环检测,默认0.5s,检测的方式在web下是执行js,app下是调用uiautomator,所以就算没有全部渲染,也是可以检测的。很多页面都是动态加载的,这期间的每个时刻dom都是完整的,只是在不断改变控件树而已。
隐式等待解决的是找控件的问题,但是等待控件消失这个就乏力了,不是做不到,而是做起来非常麻烦,所以显式等待机制就需要了。要等待的条件可以非常丰富,不再局限于简单的查找。
假设有个控件等待60s才能找到,如果用隐式等待那么其他用例也会在找不到控件的时候进行60s等待,总体用例时间会增加很多的。这也是要针对性的使用显式等待的原因。
一般默认全局隐式等待,时间比较短,不然会导致整体用例时间增长。显式等待用于剩下的所有需要等待的情况。理论上点击一个控件之前需要等待可点击的,这个需要自己封装,会让执行更稳定的。最新版本的课程里,我们就是这样教的。
有些场景下,就算可点击也是点击了没有效果的,需要用到循环点击显式等待下个控件出现这种技巧。
所以我多次提到做自动化,如果直接用原生api而不是自己封装框架,那么稳定性是很差的。
1 个赞
老师,我这样封装的行吗?
def wait_element(driver, timeout,poll,locator):
"""
:param driver: 浏览器驱动
:param timeout:超时时间
:param poll:频率,比如0.2,即每隔0.2秒查找一次
:param locator:元素定位器,是个元组
:return:
"""
used_time = 0
while used_time < timeout:
try:
elem = driver.find_element(*locator)
return elem
except:
time.sleep(poll)
used_time += poll
# 等待超时后报错
raise TimeoutError("等待超时")
你先看下显式等待的源代码吧,写的比你的好。。。
直接用即可,封装的是点击行为,而不是单个的等待。
噢噢,理解错了,意思是封装的是点击、输入等这些操作步骤,就是上课老师讲的步骤的数据驱动?
Elva
(独木森林)
12
所以隐式等待是加载页面的同时就开始查找元素了。这样的话,会不会有这种情况,页面尚未加载完成,隐式等待就已经超时?