Selenium 三种等待方式详解 (强制等待、隐式等待、显示等待)

news2024/10/7 19:19:01

前言

①在进行WEB自动化工作时,一般要等待某一页面元素加载完成后,才能对该元素执行操作,否则自动化脚本会抛出找不到元素的错误,这样就要求我们在UI自动化测试的有些场景上加上等待时间。

②等待方式的设置是保证自动化脚本稳定有效运行的一个非常重要的手段。

强制等待 sleep()

①强制等待,设置固定休眠时间。

②python 的 time 包提供了休眠方法 sleep() ; 导入 time 包后就可以使用 sleep() ,进行脚本的执行过程进行休眠。

代码如下:

# coding = utf-8
from time import sleep
from selenium import webdriver

# 驱动文件路径
driverfile_path = r'D:\coship\Test_Framework\drivers\chromedriver.exe'
# 启动浏览器
driver = webdriver.Chrome(executable_path=driverfile_path)
# 打开百度首页
driver.get(r'https://www.baidu.com/')
# 等待3秒
sleep(3)
driver.find_element_by_css_selector("#kw").send_keys("selenium")
# 退出
driver.quit()

隐式等待driver.implicitly_wait(time)

①相当于设置全局的等待,在定位元素时,对所有元素设置超时时间

②设置一个等待时间,如果在这个等待时间内,网页加载完成,则执行下一步;否则一直等待时间截止,然后再执行下一步。这样也就会有个弊端,程序会一直等待整个页面加载完成,直到超时,但有时候我需要的那个元素早就加载完成了,只是页面上有个别其他元素加载特别慢,我仍要等待页面全部加载完成才能执行下一步。

③隐式等待使得 WebDriver 在查找一个 Element 或者 Elements 数组时,每隔一段特定的时间就会轮询一次DOM,如果 Element 或 Elements 数组没有马上被发现的话。默认设置是0。一旦设置,这个隐式等待会在WebDriver对象实例的整个生命周期起作用。

# coding = utf-8
from selenium import webdriver

# 驱动文件路径
driverfile_path = r'D:\coship\Test_Framework\drivers\chromedriver.exe'
# 启动浏览器
driver = webdriver.Chrome(executable_path=driverfile_path)
# 打开百度首页
driver.get(r'https://www.baidu.com/')
driver.find_element_by_css_selector("#kw").send_keys("selenium")
driver.find_element_by_css_selector("#su").click()
# 隐式等待30秒
driver.implicitly_wait(30)
result = driver.find_elements_by_css_selector("h3.t>a")
for i in result:
    print(i.text)
# 退出
driver.quit()
现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036

显示等待

①上面我们说了隐式等待的一个弊端,如果我想等我要的元素一加载出来就执行下一步,该怎么办?这里就要用到显示等待

②显式等待是你定义的一段代码,用于等待某个条件发生然后再继续执行后续代码。

③ 在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常默认检测频率为0.5s默认抛出异常为: NoSuchElementException 。

④ WebDriverWait 的帮助文档:

>>> help(WebDriverWait)
Help on class WebDriverWait in module selenium.webdriver.support.wait:

class WebDriverWait(builtins.object)
 |  Methods defined here:
 |
 |  __init__(self, driver, timeout, poll_frequency=0.5, 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
 |
 |       element = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_i
d("someId"))
 |
 |       is_disappeared = WebDriverWait(driver, 30, 1, (ElementNotVisibleExcepti
on)).\
 |
 |                   until_not(lambda x: x.find_element_by_id("someId").is_displ
ayed())

创建一个 WebDriverWait 类的实例对象: WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

主要有4个参数:

driver :浏览器驱动

timeout :等待时间

poll_frequency :检测的间隔时间,默认0.5s

ignored_exceptions :超时后的异常信息,默认抛出NoSuchElementException

⑤显示等待要用到 WebDriverWait 类:

from selenium.webdriver.support.wait import WebDriverWait

代码示例1:

#encoding=utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

#获取单个页面元素对象,显示等待
#locateType查找的方法类型
#locatorExpression查找的表达式
def getElement(driver,locateType,locatorExpression):
    try:
        element=WebDriverWait(driver,5).until(lambda x: x.find_element(by=locateType, value=locatorExpression))
    except Exception, e:
        raise e

代码示例2:

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait

# 驱动文件路径
driverfile_path = r'D:\coship\Test_Framework\drivers\chromedriver.exe'
# 启动浏览器
driver = webdriver.Chrome(executable_path=driverfile_path)
# 打开百度首页
driver.get(r'https://www.baidu.com/')
driver.find_element_by_css_selector("#kw").send_keys("selenium")
driver.find_element_by_css_selector("#su").click()
# 超时时间为30秒,每0.2秒检查1次,直到class="tt"的元素出现
text = WebDriverWait(driver, 30, 0.2).until(lambda x:x.find_element_by_css_selector(".tt")).text
print(text)
# 退出
driver.quit()

代码示例3:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()
driver.get('http://www.baidu.com')

element = WebDriverWait(driver, 5, 0.5).until(EC.presence_of_element_located((By.ID, "kw")))
element.send_keys('selenium')

在本例中,通过as关键字将 expected_conditions 重命名为EC,并调用 presence_of_element_located() 方法判断元素是否存在。

expected_conditions 类提供的预期条件判断的方法

方法说明
title_is判断当前页面的 title 是否完全等于(==)预期字符串,返回布尔值
title_contains判断当前页面的 title 是否包含预期字符串,返回布尔值
presence_of_element_located判断某个元素是否被加到了 dom 树里,并不代表该元素一定可见
visibility_of_element_located判断某个元素是否可见. 可见代表元素非隐藏,并且元素的宽和高都不等于 0
visibility_of跟上面的方法做一样的事情,只是上面的方法要传入 locator,这个方法直接传定位到的 element 就好了
presence_of_all_elements_located判断是否至少有 1 个元素存在于 dom 树中。举个例子,如果页面上有 n 个元素的 class 都是'column-md-3',那么只要有 1 个元素存在,这个方法就返回 True
text_to_be_present_in_element判断某个元素中的 text 是否 包含 了预期的字符串
text_to_be_present_in_element_value判断某个元素中的 value 属性是否包含 了预期的字符串
frame_to_be_available_and_switch_to_it判断该 frame 是否可以 switch进去,如果可以的话,返回 True 并且 switch 进去,否则返回 False
invisibility_of_element_located判断某个元素中是否不存在于dom树或不可见
element_to_be_clickable判断某个元素中是否可见并且是 enable 的,这样的话才叫 clickable
staleness_of等某个元素从 dom 树中移除,注意,这个方法也是返回 True或 False
element_to_be_selected判断某个元素是否被选中了,一般用在下拉列表
element_selection_state_to_be判断某个元素的选中状态是否符合预期
element_located_selection_state_to_be跟上面的方法作用一样,只是上面的方法传入定位到的 element,而这个方法传入 locator
alert_is_present判断页面上是否存在 alert

Expected Conditions 的使用场景有2种:

  • 直接在断言中使用
  • 与 WebDriverWait() 配合使用,动态等待页面上元素出现或者消失

实例:

#encoding:utf-8
# example of how to use https://github.com/SeleniumHQ/selenium/blob/master/py/selenium/webdriver/support/expected_conditions.py

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By

import unittest

# dr = webdriver.PhantomJS('phantomjs')
dr = webdriver.Firefox()
# dr = webdriver.Chrome()
url = 'http://www.baidu.com'
search_text_field_id = 'kw'
dr.get(url)

class ECExample(unittest.TestCase):

  def test_title_is(self):
    ''' 判断title是否符合预期 '''
    title_is_baidu = EC.title_is(u'百度一下,你就知道')
    self.assertTrue(title_is_baidu(dr))

  def test_titile_contains(self):
    ''' 判断title是否包含预期字符 '''
    title_should_contains_baidu = EC.title_contains(u'百度')
    self.assertTrue(title_should_contains_baidu(dr))

  def test_presence_of_element_located(self):
    ''' 判断element是否出现在dom树 '''
    locator = (By.ID, search_text_field_id)
    search_text_field_should_present = EC.visibility_of_element_located(locator)

    ''' 动态等待10s,如果10s内element加载完成则继续执行下面的代码,否则抛出异常 '''
    WebDriverWait(dr, 10).until(EC.presence_of_element_located(locator))
    WebDriverWait(dr, 10).until(EC.visibility_of_element_located(locator))

    self.assertTrue(search_text_field_should_present(dr))

  def test_visibility_of(self):
    search_text_field = dr.find_element_by_id(search_text_field_id)
    search_text_field_should_visible = EC.visibility_of(search_text_field)
    self.assertTrue(search_text_field_should_visible('yes'))

  def test_text_to_be_present_in_element(self):
    text_should_present = EC.text_to_be_present_in_element((By.NAME, 'tj_trhao123'), 'hao123')
    self.assertTrue(text_should_present(dr))


  @classmethod
  def tearDownClass(kls):
    print 'after all test'
    dr.quit()
    print 'quit dr'

if __name__ == '__main__':
  unittest.main()

以title_is为例分析:

class title_is(object):
    """An expectation for checking the title of a page.
    title is the expected title, which must be an exact match
    returns True if the title matches, false otherwise."""
    def __init__(self, title):
        self.title = title

    def __call__(self, driver):
        return self.title == driver.title

可以看到 title_is 实际上是1个类,其 __call__ 方法被定义成是返回1个bool值。因此,一般的用法就是:

# 实例化
the_instance = title_is('expected')
# 直接在实例上调用__call__
the_instance(dr) #return True or False

详解webDriverWait()

WebDriverWait(self,driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None).until(self, method, message=)

或者:

WebDriverWait(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None).until_not(self,method, message=)

① self : 函数本身,在实际使用的时候不需要输入。

② driver :webdriver的驱动程序,如(IE、FireFox、chrome、safari等)。

③ timeout :超时时间,默认以秒为单位 poll_frequency ,休眠时间(步长)的间隔,默认为0.5秒,即检测元素是否存在的频率。

④ ignored_exceptions :超时后的异常信息,默认情况下抛 NoSuchElementException 异常信息,可以定义忽略的异常信息。

⑤ WebDriverWait 一般由 until 或 until_not 配合使用。

⑥ until(method, message=") :调用该方法提供的驱动程序做为一个参数,直到返回值不为 False 。

⑦ until_not(method, message=") :调用该方法提供的驱动程序做为一个参数,直到返回值为 False 。

实际应用

在自动化测试中,很多时候都会有等待页面某个元素出现后能进行下一步操作,或者列表中显示加载,直到加载完成后才进行下一步操作,但时间都不确定,如下图所示:

代码如下:

from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
import selenium.webdriver.support.expected_conditions as EC
import selenium.webdriver.support.ui as ui



# 一直等待某元素可见,默认超时10秒
def is_visible(locator, timeout=10):
    try:
        ui.WebDriverWait(driver, timeout).until(EC.visibility_of_element_located((By.XPATH, locator)))
        return True
    except TimeoutException:
        return False

# 一直等待某个元素消失,默认超时10秒
def is_not_visible(locator, timeout=10):
    try:
        ui.WebDriverWait(driver, timeout).until_not(EC.visibility_of_element_located((By.XPATH, locator)))
        return True
    except TimeoutException:
        return False

# 调用
is_not_visible('//input[@input="search-error"]') 

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!

软件测试面试小程序

被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

涵盖以下这些面试题板块:

1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

资料获取方式 :

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/988994.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

静态代理IP是什么?一文看懂静态代理IP

对于跨境玩家来说,IP代理已经是我们的老朋友了,那么什么是静态IP?有什么用?如何使用?看完这一篇你就懂了。 一、什么是静态代理IP 静态代理IP是指一个固定不变的,不会在网络重新连接时重新建立或者更改的代…

基于VS平台编译带Cuda的OpenCV(内含版本以及整套方案含泪总结)

感谢 先感谢以下帖子,确实很有参考意义,但很多坑还是没总结到(我抓狂了) 从安装到编译保姆级帖子:https://blog.csdn.net/fengxinzioo/article/details/109402921 大神版核心步骤帖子(主要参考):https://bl…

促进合作交流|旅游专业老师在加拿大访学期间取得初步成果

N老师拟申报CSC,指定国家且要求接收学校不收取板凳费,最终我们分别获得了澳大利亚科廷大学和加拿大圭尔夫大学的邀请函(均未收取板凳费)。N老师用前者申报了CSC并获批,因签证原因又用后者申请了改派,并在加…

Java之Collection集合的详细解析

1.Collection集合 1.1数组和集合的区别【理解】 相同点 都是容器,可以存储多个数据 不同点 数组的长度是不可变的,集合的长度是可变的 数组可以存基本数据类型和引用数据类型 集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类 1.2集合类体系结构【理解】 …

APUS与腾讯达成战略合作,携手深化产业赋能

9月7—8日,2023腾讯全球数字生态大会在深圳盛大举行,AI大模型企业APUS出席大会,APUS副总裁邓小波与腾讯现场签约战略合作,双方将集中各自优势,在ICT基础设施、大模型生态建设等领域开展广泛、深入合作。此外&#xff0…

mockjs+json-server模拟百万条数据

文章目录 前言场景前置操作安装axios或者Ajax(作者用的是axios)mock.js文件编辑编辑json-server文件夹添加百万条虚拟数据后言 前言 hello world 欢迎来到前端的世界 😜当前文章系列专栏:前端 🐱‍👓博主在…

G. The Morning Star

Problem - G - Codeforces 思路:想了挺长时间的,一直没想到一个简便的方法在瞎搞。我们发现对于某个点来说,其他的点如果能够跟他匹配,那么一定在这8个方向上,而同时这8个方向其实对应这4条直线,假设点为(x…

Jetpack 中 room 基本使用

Room 概述 Room 持久性库在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库,具体来说,Room具有一下优势: 1、针对SQL 查询的编译时验证。 2、可最大限度减少重复和容易出…

三、创建各个展示模块组件

简介 在文件 components 中创建轮播模块组件,引入App.vue展示。欢迎访问个人的简历网站预览效果 本章涉及修改与新增的文件:First.vue、Second.vue、Third.vue、Fourth.vue、Fifth.vue、App.vue、vite-env.d.ts、assets 一、修改vite-env.d.ts文件 /// <reference type…

Linux-Shell整理集合

Shell变量 参考文章&#xff1a; Shell脚本中变量的使用 shell语法之 , ‘ ‘ , {},, ,‘‘,(),$(())四种语法含义 参考文章&#xff1a; shell语法之 , ‘ ‘ , {},, ,‘‘,(),$(())四种语法含义 grep常用用法 Shell awk命令详解 grep 跟awk连着用&#xff1a; 获取某程序的…

索尼 toio™应用创意开发征文|联盟国战

✨ 能用众力&#xff0c;则无敌于天下矣&#xff1b;能用众智&#xff0c;则无畏于圣人矣。 —— 孙权 前言&#xff1a; 从火爆全网的ChatGPT&#xff0c;到人人都是开发者。AI无疑贯彻了整个2023年的主题&#xff0c;从刚上幼儿园的小朋友到耄耋之年的老顽童&#xff0c;都对…

Meta 验证徽章:为何大家都想在 FB 和 IG 上获得元验证

随着 Meta&#xff08;前身为 Facebook&#xff09;和 Instagram 统治数字领域&#xff0c;Meta Verified 徽章已成为真实性的终极象征。无论您是公众人物还是品牌&#xff0c;在Facebook和Instagram上获得此徽章都会对您的在线形象产生深远的影响。Facebook验证于2013年首次推…

【Python程序设计】Python 中的环境变量【05/8】

一、说明 以下文章是有关 Python 数据工程系列文章的一部分&#xff0c;旨在帮助数据工程师、数据科学家、数据分析师、机器学习工程师或其他刚接触 Python 的人掌握基础知识。本篇将讲述环境变量的问题。 迄今为止&#xff0c;本初学者指南包括&#xff1a; 第 1 部分&#xf…

算法的时间及空间复杂度

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

thinkPhp5返回某些指定字段

//去除掉密码$db new UserModel();$result $db->field(password,true)->where("username{$params[username]} AND password{$params[password]}")->find(); 或者指定要的字段的数组 $db new UserModel();$result $db->field([username,create_time…

AList dokcer安装及百度网盘挂载

AList是开源的网盘管理工具。本文介绍如何通过docker安装AList并挂载百度网盘 1、AList安装 1.1、系统安装 通过docker命令进行安装&#xff0c;命令如下: docker run -d --restartalways -v /etc/alist:/opt/alist/data -p 5244:5244 --name"alist" xhofe/alist:…

学生来看!如何白嫖内网穿透?点进来!

文章目录 前言本教程解决的问题是&#xff1a;按照本教程方法操作后&#xff0c;达到的效果是前排提醒&#xff1a; 1 搭建虚拟机1.1 下载文件vmvare虚拟机安装包1.2 安装VMware虚拟机&#xff1a;1.3 解压虚拟机文件1.4 虚拟机初始化1.5 没有搜索到解决方式&#xff1a;1.6 虚…

End-to-End Object Detection with Transformers(论文解析)

End-to-End Object Detection with Transformers 摘要介绍相关工作2.1 集合预测2.2 transformer和并行解码2.3 目标检测 3 DETR模型3.1 目标检测集设置预测损失3.2 DETR架构 摘要 我们提出了一种将目标检测视为直接集合预测问题的新方法。我们的方法简化了检测流程&#xff0c…

第三方软件信息安全测评服务范围

安全测试 第三方软件信息安全cnas资质测评服务范围&#xff1a; 1、信息安全风险评估 依据《GB/T 20984-2007 信息安全技术信息安全风险评估规范》&#xff0c;通过风险评估项目的实施&#xff0c;对信息系统的重要资产、资产所面临的威胁、资产存在的脆弱性、已采取的防护措…