(一) 前言

突然的资源受限或网络延迟,可能导致找不到目标元素,这时测试报告会显示测试失败。这时需要一种延时机制,来使脚本的运行速度与程序的响应速度相匹配,WebDriver为这种情况提供了隐式等待和显式等待两种机制。

(二) 隐式等待

一旦设置隐式等待时间,就会作用于这个WebDriver实例的整个生命周期(对所有的元素查找都生效),设置隐式等待时间后,Webdriver会在一定时间内持续检测和搜寻DOM,以便于查找一个或多个不是立即加载成功并可用的元素。隐式等待的默认时间是0. WebDriver使用implicitly_wait()来设置等待时间,单位秒。超过等待时间还没找到,就报NoSuchElementException异常。

#设置超时时间为10秒

driver.implicitly_wait(10)

(三) 显式等待

WebDriver提供了WebDriverWait类和expected_conditions模块来实现显式等待。相比隐式等待,显示等待更加智能。显示等待就是设置一个前置条件,在等待时间内,每隔一段时间检查一次前置条件是否满足,满足则执行下一步,超时则报TimeoutException异常。

(四) WebDriverWait

WebDriverWait(driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None
driver:浏览器驱动实例
timeout:等待时间,单位秒
poll_frequency:每隔多长时间检查一次,默认0.5秒
ignored_exceptions:忽略的异常,默认只有NoSuchElementException
until方法 和 until_not方法:
until(method, message=''):method指要执行的方法(等待时间内每隔一段时间,执行一次),直到返回值为true,超时则报TimeoutException异常,message将传入异常(message参数可不填)

until_not(method, message=''):直到返回值为false,其他和until相同

(五) expected_conditions模块

    expected_conditions模块提供了多种定义好的前置条件,需要配合WebDriverWait使用。

预期等待条件(前置条件)

简单说明

element_to_be_clickable(locator)

参数:locator,指一组(By,locator)

例如:WebDriverWait(driver,10).until(expected_conditions.element_to_be_clickable((By.NAME,'11')))
下面的都是以这种方式,只是前置条件不同,传的参数也可能不同
WebDriverWait(driver,10).until()
等待查找的元素可见并且可用,以便可以点击,返回定位到的元素

 

element_to_be_selected(locator)
等待直到元素被选中
invisibility_of_element_located(locator)

 

等待一个元素在DOM中不可见 或不存在
presence_of_all_elements_located(locator)

 

等待至少有一个定位器查找的元素出现在网页中,返回一组元素
presence_of_element_located(locator)

 

等待定位器查找的元素出现在网页中,或者可以在DOM中找到,返回一个被定位到的元素
text_to_be_present_in_element(locator,text)
参数:text,指定的文本
等待元素能被定位,并且带有指定的文本信息
 
title_contains(title)
参数:title,指要校验标题包含的字符串
等待网页标题包含指定的字符串,成功时返回True,否则返回false
 
title_is(title)
参数:title,指要校验的标题
等待网页标题与预期一致,成功时返回True,否则返回false
 
visibility_of(element)
参数:element,指一个元素
 
等待元素出现在DOM中,是可见的,并且宽和高都大于0,变为可见的,将返回一个元素(同一个)
 
visibility_of_element_located(locator)
 
等待元素出现在DOM中,是可见的,并且宽和高都大于0,变为可见的,将返回一个元素
 
alert_is_present()
 
判断是否存在警告窗口

 

(六) expected_conditions 示例

下面的代码,try: 部分,每一部分都是独立可用的(我只是验证不同前置条件的用法后就注释掉)。另外这里只对方法的使用方式(方法的功能)进行说明,不对使用场景进行说明(比如有没有必要这么做什么的)。

 from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By driver = webdriver.Firefox()
driver.maximize_window()
driver.get('https://www.cnblogs.com/') # try:
# #等待博客园首页的【找找看】按钮可见并可用
# search_btn = WebDriverWait(driver,10).until(expected_conditions.element_to_be_clickable((By.CLASS_NAME,'search_btn')))
# print(search_btn.get_attribute('value')) # try:
# login_area = driver.find_element_by_css_selector('#login_area')
# login = login_area.find_element_by_link_text('登录')
# login.click()
# remember_me = driver.find_element_by_id('remember_me')
# remember_me.click()
# #等待直到登录页面的复选框被选中
# WebDriverWait(driver, 10).until(expected_conditions.element_located_to_be_selected((By.ID, 'remember_me'))) # try:
# search_file = driver.find_element_by_id('zzk_q')
# search_btn = driver.find_element_by_class_name('search_btn')
# search_file.send_keys('python')
# search_btn.click()
# #网页标题是否包含 python
# WebDriverWait(driver, 10).until(expected_conditions.title_contains('python')) try:
search_file = driver.find_element_by_id('zzk_q')
#检查元素是否出现在DOM中,是可见的,并且宽和高都大于0
search_file = WebDriverWait(driver,10).until(expected_conditions.visibility_of(search_file))
print(search_file)
finally:
driver.quit()

(七) 示例(自定义前置条件)

expected_conditions类提供了多种定义好的前置条件(预期等待条件),没有前置条件符合时,也可以通过WebDriverWait自定义前置条件。

下面这个是WebDriverWait类自带的部分注释。

class WebDriverWait(object):
def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None):
"""
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())
"""

示例:(等待博客园个人主页(点击首页的园子跳转到的页面)的下拉菜单有5个可选项)

#lambda表达式其实就是一个匿名函数,冒号左边的可以理解为函数名及参数,右边的可以理解为函数的返回值,具体可以百度python lambda

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.ui import Select profile = webdriver.FirefoxProfile\
(r'C:\Users\quanhua\AppData\Roaming\Mozilla\Firefox\Profiles\tnwjkr4m.selenium')
driver = webdriver.Firefox(profile)
driver.maximize_window()
driver.get('https://home.cnblogs.com/')
try:
#等待 博客园个人主页中的下拉菜单有5个可选项
WebDriverWait(driver,10).until(lambda l:len(Select(l.find_element_by_id('sel_application')).options) == 5)
finally:
driver.quit()

(八) 总结

应用元素等待机制,对于构建高度稳定可靠的测试是必不可少的。在使用过程中,应该尽量避免隐式等待和显示等待混合使用。至于隐式等待和显示等待的优缺点,看书上和网上一般是比较推荐使用显示等待,不过我自己试了下,暂时是没看出在运行速度方面有多大区别(可能等以后有比较丰富的项目经验后,再回头来说说隐式等待和显示等待的优缺点)。

Python+Selenium笔记(十):元素等待机制的更多相关文章

  1. Python +selenium之设置元素等待

    注:本文转载http://www.cnblogs.com/mengyu/p/6972968.html 当浏览器在加载页面时,页面上的元素可能并不是同时被加载完成,这给元素的定位增加了困难.如果因为在加 ...

  2. Python+Selenium笔记(十四)鼠标与键盘事件

     (一) 前言 Webdriver高级应用的API,允许我们模拟简单到复杂的键盘和鼠标事件,如拖拽操作.快捷键组合.长按以及鼠标右键操作,都是通过使用webdriver的Python API 中的Ac ...

  3. Python+Selenium笔记(六):元素定位

      (一)  前言 Web应用以及包含超文本标记语言(HTML).层叠样式表(CSS).JS脚本的WEB页面,基于用户的操作(例如点击提交按钮),浏览器向WEB服务器发送请求,WEB服务器响应请求,返 ...

  4. WebDriver元素等待机制

    能否构建健壮和可靠的测试是UI自动化测试能否成功的关键因素之一.但实际情况是当一个测试接着一个测试执行的时候,常会遇到各种不同的状况.比如脚本去定位元素或去验证程序的运行状态时,有时会发现找不到元素, ...

  5. Selenium 3----设置元素等待

    在做Web应用的自动化测试时,定位元素必不可少,这个过程经常出现定位不到元素的情况,常见原因有哪些呢? 1.描述错误 提高编写水平.细心 2.Frame/Iframe框架原因 在元素所在框架里定位该元 ...

  6. Python+Selenium笔记(九):操作警告和弹出框

    #之前发的 driver.switch_to_alert() 这句虽然可以运行通过,但是会弹出警告信息(这种写法3.x不建议使用)  改成 driver.switch_to.alert就不会了. (一 ...

  7. selenium webdriver——设置元素等待

    如今大多数Web应用程序使用ajax技术,当浏览器在加载页面时,页面上的元素可能并不是同时被加载完成,这给定位元素的定位增加了困难, 如果因为在加载某个元素时延迟而造成ElementNotVisibl ...

  8. selenium学习之元素等待(四)

    --为什么要设置元素等待: 目前大多数web应用程序都是使用AJAX和JavaScript开发,每次加载一个网页,包括静态网页和动态网页,也就是加载各种HTML标签和JS文件.在网页中进行元素定位时, ...

  9. Python+Appium自动化测试(6)-元素等待方法与重新封装元素定位方法

    在appium自动化测试脚本运行的过程中,因为网络不稳定.测试机或模拟器卡顿等原因,有时候会出现页面元素加载超时元素定位失败的情况,但实际这又不是bug,只是元素加载较慢,这个时候我们就会使用元素等待 ...

随机推荐

  1. MySQL Cluster 日常维护

    在前面几篇文章已经详细介绍了MySQL Cluster的搭建,配置讲解.而且相信大家都掌握了基本用法.现在我们来看看Cluster的日常维护.熟悉日常维护,将有助于工作中更好的管理和使用Cluster ...

  2. CentOS7 下安装 iSCSI Target(tgt) ,使用 Ceph rbd

    目录 一.iSCSI 介绍 1. iSCSI 定义 2. 几种常见的 iSCSI Target 3. 优缺点比较 二.安装步骤 1. 关闭防火墙 2. 关闭selinux 3. 通过 yum 安装 t ...

  3. springMVC容器和Spring容器

    前段时间有人问我,为什么一定要在web.xml中配置spring的listener呢? <listener> <description>spring监听器</descri ...

  4. 了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表

    一.为什么要用小表驱动大表 1.驱动表的定义 当进行多表连接查询时, [驱动表] 的定义为: 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表] 2)未指定联接条件时,行数少的表为[驱动表 ...

  5. 程序员必知的8大排序(三)-------冒泡排序,快速排序(java实现)

    程序员必知的8大排序(一)-------直接插入排序,希尔排序(java实现) 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现) 程序员必知的8大排序(三)-------冒 ...

  6. C#调用百度地图API经验分享(二)

    接着上一篇,将上一篇代码的js提取出来:<script type="text/JavaScript">var map = new BMap.Map("allm ...

  7. [EWS]查找 文件夹

    摘要 有时在操作exchange的时候,需要查找用户exchange文件夹,比如用户新建了一些文件夹. 一个例子 这里以查找用户outlook邮箱中的历史对话文件夹为例. private const ...

  8. java自动探测文件的字符编码

    Mozilla有一个C++版的自动字符集探测算法代码,然后sourceforge上有人将其改成java版的~~ 主页:http://jchardet.sourceforge.net/ jchardet ...

  9. Killing Monsters(hdu4970)

    Killing Monsters Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...

  10. NGINX: 统计网站的PV、UV、独立IP

    做网站的都知道,平常经常要查询下网站PV.UV等网站的访问数据,当然如果网站做了CDN的话,nginx本地的日志就没什么意义了,下面就对nginx网站的日志访问数据做下统计: 概念: UV(Uniqu ...