在自动化测试脚本的运行过程中,webdriver操作浏览器的时候,对于元素的定位是有一定的超时时间,大致应该在1-3秒的样子,
如果这个时间内仍然定位不到元素,就会抛出异常,中止脚本执行。
我们可以通过在脚本中设置等待的方式来避免由于网络延迟或浏览器卡顿导致的偶然失败,常用的等待方式有三种:
强制等待
强制等待是利用python语言自带的time库中的sleep()方法:
import time
time.sleep(3)
sleep()顾明思义就是睡觉的意思,就是脚本一旦执行到条语句sleep(10)就睡10s,再执行后面的语句,他是一个强制等待的方式,使得整个脚本暂停。
但是这种方式会导致这个脚本运行时间过长,不到万不得已尽可能少用,特殊情况下,时间设置最好不超过1秒,一般0.5秒。
Appium隐式等待
隐式等待(全局)driver.implicitly_wait(20)
隐式等待相比强制等待更智能,顾明思义,在脚本中我们一般看不到等待语句,但是它会在每个页面加载的时候自动等待;
隐式等待只需要声明一次,一般在打开浏览器后进行声明。声明之后对整个drvier的生命周期都有效,后面不用重复声明。
implicitly_wait()方法用来等待页面加载完成(直观的就是浏览器tab页上的小圈圈转完),implicitly_wait(10),超时时间10s,10秒内一旦加载完成,就执行下一条语句;
如果10秒内页面都没有加载完,就超时抛出异常。
但是隐式等待依然存在一个问题,那就是程序会一直等待整个页面加载完成,也就是一般情况下你看到浏览器标签栏那个小圈不再转,才会执行下一步,
但有时候页面想要的元素早就在加载完成了,但是因为个别js之类的东西特别慢,我仍得等到页面全部完成才能执行下一步。
所以,这里webdriver提供了一种更加智能的等待方式:显示等待
隐式等待的运用 from selenium import webdriver import unittest class TestBase(unittest.TestCase): def setUp(self): self.driver=webdriver.Chrome() #驱动浏览器 self.driver.implicitly_wait(10) #设置隐式等待 self.driver.maximize_window() #最大化浏览器 def test(self): print('这是一个测试用例') def tearDown(self): self.driver.quit() if __name__=='__main__': unittest.main()
显示等待
在一个超时时间范围内,每隔一段时间去搜索一次元素是否存在,
如果存在返回定位对象,如果不存在直到超时时间到达,报超时异常错误。
// 在Appium中用了Selenium中造的轮子(显示等待) 方法:WebDriverWait(driver, timeout, poll_frequency).until(method) 参数: 1.driver:手机驱动对象 2.timeout:搜索超时时间 3.poll_frequency:每次搜索间隔时间,默认时间为0.5s 4.method:定位方法(匿名函数)
匿名函数: lambda x: x 等价于python函数: def test(x): return x
使用示例: from selenium.webdriver.support.wait import WebDriverWait WebDriverWait(driver, timeout, poll_frequency).until(lambda x: x.find_elements_by_id(id_value)) 解释: 1.x传入值为:driver,所以才可以使用定位方法. 函数运行过程: 1.实例化WebDriverWait类,传入driver对象,之后driver对象被赋值给WebDriverWait的一个类变量:self._driver 2.until为WebDriverWait类的方法,until传入method方法(即匿名函数),之后method方法会被传入self._driver 3.搜索到元素后until返回定位对象,没有搜索到函数until返回超时异常错误.
业务场景: 1.进入设置页面 2.通过ID定位方式点击搜索按钮
代码实现:
# 导入WebDriverWait类,用了selenium中的显示等待的轮子 from selenium.webdriver.support.wait import WebDriverWait # 超时时间为30s,每隔1秒搜索一次元素是否存在,如果元素存在返回定位对象并退出 search_button = WebDriverWait(driver, 30, 1).until(lambda x: x.find_elements_by_id(com.android.settings:id/search)) search_button.click() driver.quit()