在运行appium自动化脚本的过程中,有些时候由于页面加载时间过长或者升级、广告弹窗遮挡,导致无法找到对应元素而报错,为了脚本的稳定,会在适当的地方加上等待。
一般等待的方式有三种:
- 强制等待 sleep()
- 隐式等待 implicitly_wait()
- 显式等待 WebDriverWait()
sleep()
sleep() 是设置固定休眠时间。一般情况下,不推荐使用sleep(不智能,会阻塞程序流程去等,使用太多的sleep会影响脚本运行速度)。
一般脚本中在需要等待的地方
time.sleep(1) # 单位为秒。
implicitly_wait()
隐式等待 implicitly_wait() 是由webdriver提供的方法,当使用了隐式等待执行测试的时候,它并不影响脚本的执行速度。当脚本执行到某个元素定位是,如果元素可以定位,则继续执行,如果元素定位不到,则它将以轮询的方式不断地判断元素是否被定位到。
一旦设置隐式等待,会在WebDriver对象实例的整个生命周期起作用,所以只要设置一次即可(有人把隐性等待当成了sleep在用,走哪儿都来一下是不对的)。而且隐式等待会在寻找每个元素的时候都进行等待,这样会增加整个测试执行的时间。
一般在初始化完driver后,就设置隐式等待,如:
def setup(self):
caps = {}
caps["platformName"] = "Android"
caps["appPackage"] = "com.android.contacts"
caps["appActivity"] = "com.android.contacts.activities.TwelveKeyDialer"
caps["noReset"] = True
self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", caps)
self.driver.implicitly_wait(10) # 单位为秒。
WebDriverWait()
显式等待WebDriverWait()同样也是 webdirver 提供的方法。在设置时间内,默认每隔一段时间检测一次当前。页面元素是否存在,如果超过设置时间检测不到则抛出异常。
参数解析:
WebDriverWait(driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None)
"""Constructor, takes a WebDriver instance and timeout in seconds.
:Args:
- driver - Instance of WebDriver (Ie, Firefox, Chrome or Remote)
- timeout - Number of seconds before timing out
- poll_frequency - sleep interval between calls
By default, it is 0.5 second.
- ignored_exceptions - iterable structure of exception classes ignored during calls.
By default, it contains NoSuchElementException only.
Example:
from selenium.webdriver.support.ui import WebDriverWait \n
element = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_id("someId")) \n
is_disappeared = WebDriverWait(driver, 30, 1, (ElementNotVisibleException)).\ \n
until_not(lambda x: x.find_element_by_id("someId").is_displayed())
"""
一般用于处理不确定元素的方式,如打开app,有时候会弹出升级弹窗,可以用显示等待来处理升级弹窗。
代码举例:
def loaded(driver):
if len(self.driver.find_elements_by_id('cancel_btn')) >= 1:
self.driver.find_element_by_id("cancel_btn").click()
return True
else:
return False
try:
WebDriverWait(self.driver, 15).until(loaded) # 处理不确定元素的方式,如可能出现的升级弹窗之类,不过也只能针对已知页面的不确定性弹窗,对于不确定哪个页面的弹窗,之后会介绍watch机制
except:
print('no update')
显式等待和隐式等待的区别
-
隐式等待
- 只能用于元素定位
- 通过appium server设置轮循条件,一个webdriver周期只需要设置一次
-
显式等待
- 使用场景和条件都非常灵活
- 为本地用例层轮循条件