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种等待机制(包括默认的),有了这些等待,可以大大的提高我们测试的准确性和稳定性。这几种机制没有哪个最好,我们需要根据实际的情况选择最合适的等待。

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

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

相关文章

pycharm如何有效读取到win10设置的环境变量

参考链接&#xff1a; 参考文章 该参考文章的第一种方法&#xff1a;设置win10环境变量。 在设置完环境变量后&#xff0c;在pycharm终端上不能有效读取到刚刚设置的环境变量的&#xff0c;需要启动win的cmd&#xff0c;在项目路径下执行脚本。如下所示的对比&#xff1a; cm…

金航标kinghelm萨科微slkor公司发展和品牌传播

为了金航标kinghelm萨科微slkor公司发展和品牌传播&#xff0c;推出了”金航标每日芯闻“与“萨科微每日芯闻“栏目&#xff0c;影响力非常好。这一构想并非一时的灵光乍现&#xff0c;而是经过深思熟虑和充分调研的结果。制定该栏目的模板时候时&#xff0c;就明确了要求语音版…

棒材直线度测量仪 专为圆形产品研发设计 在线无损检测

棒材直线度测量仪采用了先进的技术&#xff0c;能够实现在线无损检测&#xff0c;为生产过程提供了极大的便利。专为圆形产品设计&#xff0c;它能够精确测量棒材的米直线度及外径、椭圆度尺寸&#xff0c;为质量控制提供可靠的数据支持。 在线直线度测量仪不仅具有出色的性能…

Web前端开发 - 4 - CSS3动画

CSS3动画 一、 设计2D变换二、 设计3D变换三、 设计过渡动画四、设计帧动画 一、 设计2D变换 transform : none | <transform-function> /* <transform-function> 设置变换函数&#xff0c;可以是一个或多个变换函数列表。函数包括: martrix(x缩放,x倾斜,y倾斜,y…

刷代码随想录有感(66):回溯算法——组合问题的优化(剪枝)

代码&#xff1a;将for循环中i的搜索范围进行缩小&#xff0c;免去多余的不可能符合条件的操作。 for(int i start; i < n-(k-tmp.size())1;i) 实质是剪枝&#xff0c;拿n4,k4作比较&#xff1a; 显然结果只可能是[1,2,3,4]&#xff0c;选取顺序只可能是1-2-3-4&#xff…

c#多态性的应用

设计一个电脑游戏&#xff0c;游戏中有猪、牛、兔子、青蛙、鸭子等动物&#xff0c;这些动 物都继承于Vertebrata 类&#xff08;脊椎动物类&#xff09;&#xff0c;Vertebrata类有一个抽象方法Display()&#xff0c;每个动 物都从Vertebrata 类那里继承并重写了Display()方法…

windows下mysql5.6下载安装(多实例安装)

目录 1、下载 2、安装步骤 3、mysql多实例安装 1、下载 http://dev.mysql.com/downloads/windows/installer/5.6.html 2、安装步骤 我们采用自定义安装模式&#xff1a;选择32位或64位 默认即可&#xff1a; 说明&#xff0c;如果没有该页面就上一步&#xff0c;选择高级选…

OpenAI推出旗舰AI模型GPT-4o并免费开放

&#x1f989; AI新闻 &#x1f680; OpenAI推出旗舰AI模型GPT-4o并免费开放 摘要&#xff1a; OpenAI 未来的产品将以免费为优先&#xff0c;以让更多人使用为目标。OpenAI 发布了桌面版本的程序和更新后的 UI&#xff0c;更加简单自然。推出了新一代大模型 GPT-4o&#xf…

经典神经网络(8)GAN、CGAN、DCGAN、LSGAN及其在MNIST数据集上的应用

经典神经网络(8)GAN、CGAN、DCGAN、LSGAN及其在MNIST数据集上的应用 1 GAN的简述及其在MNIST数据集上的应用 GAN模型主导了生成式建模的前一个时代&#xff0c;但由于训练过程中的不稳定性&#xff0c;对GAN进行扩展需要仔细调整网络结构和训练考虑&#xff0c;因此GANs虽然在…

金融科技员工一年赚多少钱?富如恒生电子,穷如长亮科技

在本篇文章中&#xff0c;我们继续分析四家金融科技公司的数据&#xff0c;本次站在员工视角来看&#xff08;链接&#xff0c;这四家公司的更详细内容&#xff09;。 先说结论。 2023年&#xff0c;如果你是恒生电子的普通员工&#xff0c;那年薪在35万元&#xff1b;如果你在…

OSPF多区域通信基础实验

基本概念了解&#xff1a; 网络设备接口速率、 Ethernet 100MB GE 1000MB serial接口 1.544MB area 0 骨干区域&#xff08;backbone&#xff09; area 0area0.0.0.0 不是area 0 非骨干区域 ar area 256area 0.0.1.0 实验拓扑如下&#xff1a;要求PC1能够访问PC2 &#xff08;跨…

oracle多条重复数据,取最新的

1、原理讲解-可直接看2 筛选出最新的 SELECT * FROM ( SELECT t.*, ROW_NUMBER() OVER (PARTITION BY LOCALAUTHID ORDER BY LASTUPDATETIME DESC) AS rn FROM USER_LOCALAUTH_STATE t ) t WHERE t.rn 1; 解释&#xff1a; 这个序号是基于[LOCALAUTHID]字段进行分…

外网ip地址怎么获取?快解析

大家都清楚互联网是通过ip地址通信的&#xff0c;ip地址又分内网ip和外网ip。内网ip只能在内网使用&#xff1b;而外网ip作为电脑唯一标识&#xff0c;可在公网使用。那么外网ip地址怎么获取呢&#xff1f; 外网ip是网络运营商分配给用户的。目前最常见的两种上网方式一个是拉…

图文详解JUC:Wait与Sleep的区别与细节

目录 一.Wait() 二.Sleep() 三.总结Wait()与Sleep()的区别 一.Wait() 在Java中&#xff0c;wait() 方法是 Object类中的一个方法&#xff0c;用于线程间的协作。当一个线程调用wait() 方法时&#xff0c;它会释放对象的锁并进入等待状态&#xff0c;直到其他线程调用相同对…

JVM调优-调优原则和原理分析

1.写在前面 对于JVM调优这个话题&#xff0c;可能大部分程序员都听过这个名词。 但是绝大多数程序员&#xff0c;都没有真真实实去干过&#xff0c;都没有真实的实践过。也不懂得如何调优&#xff1f;不知道要调成怎么样&#xff1f; 那今天咋们就对这个话题来展开描述一下&…

洛谷 P3372:线段树 1 ← 分块算法模板(区间更新、区间查询)

【题目来源】https://www.luogu.com.cn/problem/P3372【题目描述】 如题&#xff0c;已知一个数列&#xff0c;你需要进行下面两种操作&#xff1a; &#xff08;1&#xff09;将某区间每一个数加上 k。 &#xff08;2&#xff09;求出某区间每一个数的和。【输入格式】 第一行…

二叉树——初解

二叉树 树树的概念树的性质 二叉树二叉树的概念二叉树的性质二叉树的实现方式数组构建左孩子右兄弟法构建指针构建 树 树的概念 在计算机科学中&#xff0c;树&#xff08;Tree&#xff09;是一种重要的非线性数据结构&#xff0c;它由若干节点&#xff08;Node&#xff09;组…

Chromium 调试指南2024 Windows11篇-调试变量监视(十)

1. 前言 设置断点和监视变量是调试过程中常用的两种技术手段。通过设置断点&#xff0c;我们可以暂停程序的执行并检查程序的内部状态&#xff0c;而监视变量则可以帮助我们实时查看程序中关键变量的值。本文将介绍如何在Chromium项目中进行断点设置和变量监视&#xff0c;帮助…

java内容快速回顾+SSM+SpringBoot简要概述

文章目录 java基础知识基本知识列表面对对象堆与栈的关系值修改与引用修改异常&#xff1a;错误异常 SSMspringMVCServletSpringMVC&#xff1a;基于 Servlet的 Spring Web 框架&#xff0c; spring控制反转 IoC(Inversion of Control)面向切面 Aop MybatisJDBCMybatis SpringB…

Git 基础使用(1) 入门指令

文章目录 Git 作用Git 安装Git 使用Git 仓库配置Git 工作原理Git 修改添加Git 查看日志Git 修改查询Git 版本回退 概念补充 Git 作用 Git 是一种分布式版本控制系统&#xff0c;它旨在追踪文件和文件夹的更改&#xff0c;并协助多人协作开发项目。 Git 安装 &#xff08;Lin…