标题目录
一、前言
1、强制等待是sleep,强烈不推荐,设定的时间太固定,如果是模拟器等待3秒,真机可能只需要等待2秒。
2、driver.implicitly.wat(timeout) ,贯穿全部元素的等待,只需要设定一次即可,通常是在创建driver的时候后的代码运行,是dom建立之后的等待。
3、显式等待是在客户端的等待:引用连个包和一个例子
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
WebDriverWait(self.driver,10).until(expected_conditions.element_to_be_clickable(loca tor))
二、强制等待
强制等待,线程休眠一定时间。
import time time.sleep(3)
三、隐式等待
隐式等待,就是在创建driver时,设置全局元素等待超时时间。
当要查找元素,而这个元素没有马上出现时,告诉 WebDriver 查询 Dom 一定时间,实际上浏览器会在你自己设定的时间内不断的刷新页面去寻找我们需要的元素。
默认值是 0.5秒,但是设置之后,这个时间将在WebDriver 对象实例整个生命周期都起作用。(处理 Table 对象时,需要将此设置为默认值)
self.driver.implicitly_wait(10)
设置等待时长为10秒,首先这10秒并非一个固定的等待时间,它并不影响脚本的执行速度。其次,它并不针对页面上的某一元素进行等待。
当脚本执行到某个元素定位是,如果元素可以定位,则继续执行,如果元素定位不到,则它将以轮询的方式不断地判断元素是否被定位到。
假设在第六秒定位到了元素则继续执行,若直到超出设置的时长10秒还没有定位到元素,则抛出异常。
四、显式等待
1、显式等待的简介
(1)显式等待与隐式等待相对,显式等待必须在每一个需要等待的元素前面进行声明。
(2)是针对某个特定的元素设置等待时间,在设置时间内,默认每隔一段时间检测一次当前某个元素是否存在。
(3)如果在规定的时间内找到元素,则直接执行,即找到元素就执行相关操作。
(4)如果超过设置时间检测不到就抛出异常,默认检测频率为0.5s,默认抛出的异常时NoSuchElementException。
(5)用到的两个常用类:
WebDriverWait
expected_condition
2、为什么要用显式等待,为什么隐式等待无法替代显式等待?
(1)显式等待可以等待动态加载的ajax元素,需要配合expected_condition来检查条件。
(2)一般页面上元素的呈现顺序是:
首先出现title。
然后是dom树的出现,presence还不完整,dom树出现就是隐式等待了,但此时的元素可能还没有是可点击的状态,所以只用隐式等待,使用click方法,肯定会报错的。
css出现:可见visbility。
js的出现,js特效执行:可点击clickable。
(3)html文档是自上而下加载的。
(4)js文件加载会阻塞html内容的加载,有些js异步加载的方式来完成js的加载 样式表下载完成之后跟之前的样式表一起进行解析,会对之前那的与元素重新渲染。
(5)presence-visibility-clickabe,元素出现-可见-可点击,是元素的三个性质,当DOM树出现时,定位元素可能已经显示出来了,但是可见和可点击的属性可能还没加载出来,这时候元素的一些方法是不可用的,比如 element.click() ,要等到js渲染出来以后,元素的click属性才可以用。
对应 element.is_displayed()
对应 element.is_selected()
对应 element.is_enabled()
3、js的同步加载和异步加载
同步加载:同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止了后续的解析,因此停止了后续的文件加载(如图像)、渲染、代码执行。
异步加载:异步加载又叫非阻塞,浏览器在下载执行 js 同时,还会继续进行后续页面的处理。
4、WebDriverWait用法
WebDriverWait(self, driver, timeout, poll_frequency=POLL_FREQUENCY,
ignored_exceptions=None)
driver:浏览器驱动
timeout:超时时间,单位秒
poll_frequency:检查的间隔步长,默认是0.5s
ignored_exceptions:超时最后的抛出的异常,默认是NoSuchElementException
通常我们只会用到driver和timeout
WebDriverWait().unti(self, method, message=’’) or until_not()的方法:
(1)method:在等待期间,每个一段时间(__init__中的poll_frequency)调用这个传入的方法,直到返回值不是False
(2)message:如果超时,抛出
TimeoutException,将message传入异常
(3)until not:是当某个元素小时或什么条件则继续执行,参数也相同
5、expected_conditions类
appium直接帮我们封装好了类,只需要传参数即可,比如我们使用的是click(),只需要判断这个元素是否可点击属性才继续点击。
用法:expected_conditions.element_to_be_clickable(locator) ,其中locator就是:(By.ID,
“com.xueqiu.android:id/tv_search”)
常用的几个如下:
expected_conditions.element_to_be_clickable :元素是否可点击
expected_conditions.presence_of_element_located :元素是否被加到dom树里面
expected_conditions.visibility_of_element_located :元素是否可见
6、lambda获取元素
#可以获取到元素 element = WebDriverWait(self.driver, 10).until(lambda x: x.find_element(By.XPATH,'//* [@text="我的"]')) #这里找到元素后,不用等待,实测证明过了 element.click()
显式等待
使webdriver等待某个条件成立时继续执行,否则在最大时长时抛出超时溢出。
from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def find_element(self,*loc): '''寻找元素''' try: WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc)) #显示 等待 return self.driver.find_element(*loc) except: print('%s页面未找到元素'% loc)
until:
'''隐式等待和显示等待都存在时,超时时间取二者中较大的''' locator = (By.ID,'kw') driver.get(base_url) WebDriverWait(driver,10).until(EC.title_is(u"百度一下,你就知道")) '''判断title,返回布尔值''' WebDriverWait(driver,10).until(EC.title_contains(u"百度一下")) '''判断title,返回布尔值''' WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw'))) '''判断某个元素是否被加到了dom树里,并不代表该元素一定可见,如果定位到就返回WebElement''' WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,'su'))) '''判断某个元素是否被添加到了dom里并且可见,可见代表元素可显示且宽和高都大于0''' WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(by=By.ID,value='kw')) ) '''判断元素是否可见,如果可见就返回这个元素''' WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'.mna v'))) '''判断是否至少有1个元素存在于dom树中,如果定位到就返回列表''' WebDriverWait(driver,10).until(EC.visibility_of_any_elements_located((By.CSS_SELECTOR,'.m nav'))) '''判断是否至少有一个元素在页面中可见,如果定位到就返回列表''' WebDriverWait(driver,10).until(EC.text_to_be_present_in_element((By.XPATH,"//* [@id='u1']/a[8]"),u'设置')) '''判断指定的元素中是否包含了预期的字符串,返回布尔值''' WebDriverWait(driver,10).until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR,'# su'),u'百度一下')) '''判断指定元素的属性值中是否包含了预期的字符串,返回布尔值''' #WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it(locator)) '''判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False''' #注意这里并没有一个frame可以切换进去 WebDriverWait(driver,10).until(EC.invisibility_of_element_located((By.CSS_SELECTOR,'#swfE veryCookieWrap'))) '''判断某个元素在是否存在于dom或不可见,如果可见返回False,不可见返回这个元素''' #注意#swfEveryCookieWrap在此页面中是一个隐藏的元素 WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//* [@id='u1']/a[8]"))).click() '''判断某个元素中是否可见并且是enable的,代表可点击''' driver.find_element_by_xpath("//*[@id='wrapper']/div[6]/a[1]").click() #WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//* [@id='wrapper']/div[6]/a[1]"))).click() #WebDriverWait(driver,10).until(EC.staleness_of(driver.find_element(By.ID,'su'))) '''等待某个元素从dom树中移除''' #这里没有找到合适的例子 WebDriverWait(driver,10).until(EC.element_to_be_selected(driver.find_element(By.XPATH,"// *[@id='nr']/option[1]"))) '''判断某个元素是否被选中了,一般用在下拉列表''' WebDriverWait(driver,10).until(EC.element_selection_state_to_be(driver.find_element(By.XP ATH,"//*[@id='nr']/option[1]"),True)) '''判断某个元素的选中状态是否符合预期''' WebDriverWait(driver,10).until(EC.element_located_selection_state_to_be((By.XPATH,"//* [@id='nr']/option[1]"),True)) '''判断某个元素的选中状态是否符合预期''' driver.find_element_by_xpath(".//*[@id='gxszButton']/a[1]").click() instance = WebDriverWait(driver,10).until(EC.alert_is_present()) '''判断页面上是否存在alert,如果有就切换到alert并返回alert的内容''' print instance.text instance.accept() driver.close()
五、最后
对软件测试、接口测试、自动化测试、软件测试零基础入门、性能测试、LR脚本开发、python自动化全栈、面试经验感兴趣可以175317069,群内会有不定期的发放免费的资料链接。如果你有好的学习也资料可以私聊发我,我会注明出处之后分享给大家。