当前位置: 首页 > news >正文

Selenium 自动化 —— 四种等待(wait)机制

 更多关于Selenium的知识请访问CSND论坛“兰亭序咖啡”的专栏:专栏《Selenium 从入门到精通》


目录

目录

需要等待的场景

自己实现等待逻辑

Selenium 提供的三种等待机制

隐式等待(Implicit Waits)

隐式等待的优点

隐式等待的缺点

显式等待(Explicit Waits)

显式等待的优点

显式等待的缺点

自定义等待(Custom Waits)

自定义等待的优点

自定义等待的缺点

总结


需要等待的场景

在 UI 自动化时,我们通常需要等待,比如以下场景:

  •  登录后,页面会跳转,我们需要等待页面完全加载(否则,没ready访问元素会找不到
  • 点击搜索按钮后,页面异步刷新,我们需要等待加载框消失(否则,结果还没有update,拿到错误的数据
  • 页面满足部分条件后,预定按钮才会可以点击,我们需要等待它变成激活状态(否则,按钮还是disabled的状态,出现点击报错
  • ……

总之,这些等待,对于我们测试的稳定性和正确性非常重要。

自己实现等待逻辑

最简单的方法是,我们自己写一个While循环不断地检查条件是否满足。

while(true){if(checkCondition()){doSomeThing();}else{Thread.sleep(n秒);}
}

不过这么做不但麻烦,自己实现也容易出错。值得庆幸的是,Selenium 就提供了内置的机制,帮助我们实现等待的功能。

学习中可以造轮子,帮助我们理解原理,但是生产项目中尽量用成熟的轮子。

Selenium 提供的三种等待机制

Selenium 查找元素默认是没有等待的,也就是说找到了就返回WebElement,否则就抛出异常。

我们测试一下,没有配置任何等待:

@Test
public void testDefault(){WebDriver driver = null;long begin = 0;try{driver = new ChromeDriver();driver.get("https://mail.163.com");begin = System.currentTimeMillis();WebElement element = driver.findElement(By.id("inexistence"));}finally {long end = System.currentTimeMillis();log.info("花费时间:{}毫秒", end-begin);driver.close();}
}

日志打印:-- 花费时间:100毫秒(这个很短的时间是findElement本身执行遍历dom需要的一些时间

抛出异常:

org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#inexistence"}

Selenium 提供了等待机制,我们可以通过配置或者调用,很方便的实现我们等待的需求。

Selenium 主要分为:

  1. 显式等待(Explicit Waits)
  2. 隐式等待(Implicit Waits)
  3. 自定义等待(Custom Waits)

 下面我们分别介绍它们。

隐式等待(Implicit Waits)

隐式等待是全局设置,设置一次后,对整个WebDriver实例生命周期内的所有查找元素操作生效。

它会让Webdriver在寻找元素时,如果元素没有立即找到,就等待一段时间再查找,直到超过设定的最大时间或者找到元素为止。

下面是我们显式等待的测试代码:

@Test
public void testImplicit (){WebDriver driver = null;long begin = 0;try{driver = new ChromeDriver();// 设置隐式等待时间为10秒driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));driver.get("https://mail.163.com");WebElement element = driver.findElement(By.id("inexistence"));}finally {long end = System.currentTimeMillis();log.info("花费时间:{}毫秒", end-begin);driver.close();}
}

其实相对于默认的机制,我们只是加了一行配置的代码:

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

但是效果却非常大:

日志打印:-- 花费时间:10129毫秒(去除方法本身的执行时间,等待时间大于就是10秒

抛出的异常还是找不到元素:

org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#inexistence"}

当然不是说一定要等待这么久,如果找到了元素,会立刻返回!

等待时间只是超时时间。

隐式等待的优点

简单,一条配置,全局都有效。

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

隐式等待的缺点

等待的时间是全局的,但是不同元素、不同页面、甚至不同网络的加载情况不一样,不能对每种元素设置不同的等待时间。

使用不当的话,会对整个测试的效率造成非常大的影响。

比如,我们很多地方会用检查一个元素存不存在,来判断不同的情况。

Element ele = findElement(XXX);
if(ele == null){ // 当然默认找不到元素会抛异常而不是为null,不过我们可以使用findElementsdoSometing();
}else{doOtherthing();
}

如果很多地方都这样检查,那么花费的时间会很长很长!

显式等待(Explicit Waits)

上面说过,隐式等待是全局一致的,如果我们想更灵活的等待,对一些元素希望等待时间可以短一些,对另一些希望能够多等一些时间,这时显式等待就派上用场了。

@Test
public void testExplicitWait(){WebDriver driver = null;long begin = 0;try{driver = new ChromeDriver();driver.get("https://mail.163.com");begin = System.currentTimeMillis();// 等待id为"someId"的元素出现WebElement element = new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.presenceOfElementLocated(By.id("someId")));// 等待加载图标(class为"loading-spinner")消失new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.invisibilityOfElementLocated(By.className("loading-spinner")));}finally {long end = System.currentTimeMillis();log.info("花费时间:{}毫秒", end-begin);driver.close();}
}

可以看到,我们可以对不同的元素设置不同的等待时间

new WebDriverWait(driver, java.time.Duration.ofSeconds(10))

这些wait,其实也是可以复用的,比如10s的等待的Wait,可以被用来检查各种元素。

还能对它们设置不同的条件,比如等待元素的出现、消失

wait.until(ExpectedConditions.presenceOfElementLocated(By.id("someId")));
wait..until(ExpectedConditions.invisibilityOfElementLocated(By.className("loading-spinner")));

ExpectedConditions 类内置了常用的各种等待条件,满足我们大部分的场景:

更完整的列表,请查看这个类的方法列表

显式等待的优点

更精细更灵活的控制:

1. 对不同的元素设置不同的等待时间

2. 对不同的元素设置不同的等待条件

显式等待的缺点

更复杂,维护起来也麻烦。

如果不是很熟悉,乱使用,容易适得其反。

自定义等待(Custom Waits)

显式等待看上去很强大了,是不是就很完美了呢?

特殊场景下,如果你又更苛刻的要求,你也可以定制化自己的等待,进一步的更精细的控制等待,比如:

  •  自定义重试检查的周期
  • 找不到抛异常时,想根据Exception做一些处理(因为隐式、显式等待超时后都是直接抛出Timeout异常的,默认不做处理往外抛)
  • 定制超时后的异常消息文本
    @Testpublic void test() {WebDriver driver = null;long begin = 0;try {driver = new ChromeDriver();driver.get("https://mail.163.com");begin = System.currentTimeMillis();Wait<WebDriver> wait =new FluentWait<>(driver).withTimeout(Duration.ofSeconds(2)).pollingEvery(Duration.ofMillis(300)).ignoring(ElementNotInteractableException.class);wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("no-no")));} finally {long end = System.currentTimeMillis();log.info("花费时间:{}毫秒", end - begin);driver.close();}}

自定义等待的优点

更灵活、更精细的控制

自定义等待的缺点

太复杂,使用前请认真思考,我们真的需要这么细致的控制吗?

总结

本文介绍了4种等待机制(包括默认的),有了这些等待,可以大大的提高我们测试的准确性和稳定性。这几种机制没有哪个最好,我们需要根据实际的情况选择最合适的等待。

相关文章:

Selenium 自动化 —— 四种等待(wait)机制

更多关于Selenium的知识请访问CSND论坛“兰亭序咖啡”的专栏&#xff1a;专栏《Selenium 从入门到精通》 ​ 目录 目录 需要等待的场景 自己实现等待逻辑 Selenium 提供的三种等待机制 隐式等待&#xff08;Implicit Waits&#xff09; 隐式等待的优点 隐式等待的缺点 …...

每日两题 / 437. 路径总和 III 105. 从前序与中序遍历序列构造二叉树(LeetCode热题100)

437. 路径总和 III - 力扣&#xff08;LeetCode&#xff09; 前序遍历时&#xff0c;维护当前路径&#xff08;根节点开始&#xff09;的路径和&#xff0c;同时记录路径上每个节点的路径和 假设当前路径和为cur&#xff0c;那么ans 路径和(cur - target)的出现次数 /*** D…...

matlab使用2-基础绘图

matlab使用2-基础绘图 文章目录 matlab使用2-基础绘图1. 二维平面绘图2. 三维立体绘图3. 图形窗口的分割 1. 二维平面绘图 % 创建一些二维数据 x 0:0.01:10; % x轴的数据点&#xff0c;从0到10&#xff0c;间隔为0.01 y sin(x); % y轴的数据点&#xff0c;是x的正弦…...

嵌入式开发四大平台介绍

MCU&#xff08;Micro Control Unit&#xff09;四大平台介绍&#xff09; 单片机优点&#xff1a;缺点&#xff1a;总结&#xff1a; DSP digital signal processingARM优点&#xff1a;缺点&#xff1a;总结 FPGA什么事FPGA&#xff08;集成元件库&#xff09;FPGA开发方法—…...

《Python编程从入门到实践》day28

# 昨日知识点回顾 安装Matplotlib 绘制简单的折线图 # 今日知识点学习 15.2.1 修改标签文字和线条粗细 # module backend_interagg has no attribute FigureCanvas. Did you mean: FigureCanvasAgg? # 解决办法&#xff1a;matplotlib切换图形界面显示终端TkAgg。 #…...

STC8增强型单片机开发【定时器Timer⭐】

目录 一、引言 二、定时器基础知识 三、STC8定时器配置 四、代码示例 五、总结 一、引言 在单片机开发中&#xff0c;定时器&#xff08;Timer&#xff09;是一个极其重要的组件&#xff0c;它允许开发者基于时间触发各种事件或任务。STC8增强型单片机作为一款功能丰富的…...

C语言实训项目源码-02餐厅饭卡管理系统-C语言实训C语言大作业小项目

C语言餐厅饭卡管理系统 一、主要功能 主要功能模块 页面名称 实现功能 负责人 进入页面 进入程序 主函数 系统主要功能 修改密码函数 修改密码 充值&#xff0c;显示函数 饭卡充值与信息显示 购买饭菜…...

Linux第四节--常见的指令介绍集合(持续更新中)

点赞关注不迷路&#xff01;本节涉及初识Linux第四节&#xff0c;主要为常见的几条指令介绍。 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1f44d;&#x1f3fb; 收藏 ✨ 加关注&#x1f440; 期待与你共同进步! 1. more指令 语法&#xff1a;more [选项][文件]…...

Apache Sqoop:高效数据传输工具搭建与使用教程

目录 引言一、环境准备二、安装sqoop下载sqoop包解压文件 三、配置Sqoop下载mysql驱动拷贝hive的归档文件配置环境变量修改sqoop-env.sh配置文件替换版本的commons-lang的jar包 验证Sqoop安装查看Sqoop版本测试Sqoop连接MySQL数据库是否成功查看数据库查看数据表去除警告信息 四…...

【C++初阶】第十一站:list的介绍及使用

目录 list的介绍及使用 1.list的含义 2.list的介绍 3.list的使用 1.list的构造 2.list iterator的使用 3.list capacity 4.list element access 5 list modifiers 尾插尾删 和 头插头删 insert 和 erase resize swap clear 6.list sort and reverse 7.list copy vector copy li…...

【devops】Linux 日常磁盘清理 ubuntu 清理大文件 docker 镜像清理

日常磁盘清理 1、查找大文件 find / -type f -size 1G2、清理docker无用镜像&#xff08;drone产生的残余镜像文件&#xff09; docker system prune -a一、清理服务器磁盘 1、查找大文件 在Ubuntu系统中&#xff0c;你可以使用find命令来查找大文件。find命令是一个强大的…...

2024年资阳市企业技术中心申报条件、流程要求及支持政策须知

第一章 总则 第一条 为深入贯彻中央、省、市大力实施创新驱动发展战略的部署要求&#xff0c;进一步强化企业技术创新主体地位&#xff0c;引导和支持企业增强技术创新能力&#xff0c;健全技术创新市场导向机制&#xff0c;规范我市企业技术中心&#xff08;下称“市企业技术…...

社交媒体数据恢复:如流

如流&#xff0c;原名百度Hi&#xff0c;是百度公司开发的一款即时通讯软体。百度Hi具备文字消息、视讯、通话、文件传输等功能。 查找备份&#xff1a;如果您之前有备份如流中的数据&#xff0c;您可以尝试从备份中恢复。如流支持备份至云端&#xff0c;如百度网盘等。 联系客…...

【微信小程序开发(从零到一)【婚礼邀请函】制作】——任务分析和效果实现的前期准备(1)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…...

独孤思维:模仿别人赚钱太难,很痛苦

01 独孤早年混群的时候&#xff0c;想着成为群红&#xff0c;引流。 结果不得其法&#xff0c;别人要什么项目&#xff0c;我就把满是钩子的副业资料发群里。 被群主踢了出去。 我当时还不理解。 后来自己做了社群以后&#xff0c;才明白&#xff0c;这种行为&#xff0c;…...

图片转base64【Vue + 纯Html】

1.template <el-form-item label"图片"><div class"image-upload-container"><input type"file" id"imageUpload" class"image-upload" change"convertToBase64" /><label for"imageU…...

【从零开始学习Redis | 第十一篇】快速介绍Redis持久化策略

前言&#xff1a; Redis 作为一种快速、高效的内存数据库&#xff0c;被广泛应用于缓存、消息队列、会话存储等场景。然而&#xff0c;由于其特性是基于内存的&#xff0c;一旦服务器进程退出&#xff0c;内存中的数据就会丢失。为了解决这一问题&#xff0c;Redis 提供了持久…...

在Ubuntu中如何解压zip压缩包??

2024年5月15日&#xff0c;周三上午 使用 unzip 命令 unzip 文件名.zip这会将压缩包中的内容解压到当前目录。如果想解压到特定目录&#xff0c;可以使用 -d 选项&#xff0c;例如&#xff1a; unzip 文件名.zip -d 目标目录使用 7-zip 还可以安装 7-zip 工具来解压 ZIP 文件。…...

LeetCode 126题:单词接龙 II

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…...

5.14(Vue2)

1.单页应用程序是指所有功能都在一个html页面上 单页面应用程序&#xff0c;之所以开发效率高&#xff0c;性能好&#xff0c;应用体验好&#xff0c;最大的原因就是&#xff1a;页面按需更新。 2.Vue中的路由 路径和组件的映射关系 Vue中的路由插件&#xff1a;VueRouter&…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

加密通信 + 行为分析:运营商行业安全防御体系重构

在数字经济蓬勃发展的时代&#xff0c;运营商作为信息通信网络的核心枢纽&#xff0c;承载着海量用户数据与关键业务传输&#xff0c;其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级&#xff0c;传统安全防护体系逐渐暴露出局限性&a…...

AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)

Name&#xff1a;3ddown Serial&#xff1a;FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名&#xff1a;Axure 序列号&#xff1a;8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...