《手把手教你》系列技巧篇(二十四)-java+ selenium自动化测试-三大延时等待(详细教程)

简介: 【4月更文挑战第16天】本文介绍了Selenium的三种等待方式:硬性等待、隐式等待和显式等待。硬性等待是指无论页面是否加载完成,都会等待指定时间后再执行下一步;隐式等待是在整个会话中设置一个全局等待时间,如果元素在规定时间内出现则执行,否则继续等待;显式等待是更加灵活的等待方式,可以指定特定条件,如元素可见、可点击等,只有当条件满足时才会执行下一步。

1.简介

前边讲解完八大元素定位大法,今天宏哥讲解和分享一下三大延时等待。宏哥这里简称“三等八定”。很多人在群里问,这个下拉框定位不到、那个弹出框定位不到…各种定位不到,其实大多数情况下就是两种问题:1. 有frame,2. 没有加等待。殊不知,你的代码运行速度是什么量级的,而浏览器加载渲染速度又是什么量级的,就好比闪电侠和凹凸曼约好去打怪兽,然后闪电侠打完回来之后问凹凸曼你为啥还在穿鞋没出门?凹凸曼分分中内心一万只羊驼飞过,欺负哥速度慢,哥不跟你玩了,抛个异常撂挑子了。

那么怎么才能照顾到凹凸曼缓慢的加载速度呢?只有一个办法,那就是等喽。说到等,又有三种等法,且听宏哥一一道来。

2.为啥要等待?

有时候我们做自动化测试,需要等待。因为我们的下一步执行依赖于上一步的执行结果,因为程序执行的是很快的,上一步执行完毕马上执行下一步,有时候上一步的结果还没加载出来,下一步就执行了,这样就会造成错误,比如No suchElement Exception有时候就是因为这样造成的。

我们经常会碰到用selenium操作页面上某个元素的时候,需要等待页面加载完成后, 才能操作。 否则页面上的元素不存在,会抛出异常。

或者碰到AJAX异步加载,我们需要等待元素加载完成后,才能操作。在进行UI自动化测试时,需要等元素加载完成,才能对元素进行操作,不然找不到元素会报错,因此需要增加等待在上篇selenium+java元素定位的使用中。

3.Selenium的三大等待

3.1硬性等待(sleep)

先讲强制等待,大家应该都不会陌生,sleep就是强制等待。硬性等待也称为强制等待、线程休眠。强制等待,顾名思义就是强迫你等待呗,你等也得等不等也得等,没有商量。不管页面是否加载完,强制指定等待时间后继续执行。不建议用这种方式。此种等待方法直接调用Thread.sleep()方法来进行线程等待,由于此方法较为死板,不够灵活,会导致脚本运行时间变长,故建议尽量少用

Thread.sleep():固定休眠时间设置,Java的Thread类里提供了休眠方法sleep,导入包后就能使用

sleep()方法以毫秒为单位  

只要在case中加入sleep就会强制等待设置的时间后才会执行之后的命令,这种等待一般适用于调试脚本的时候。

java代码,采用方式如下:

Thread.sleep(3000);----------表示线程等待3秒,执行到此时不管什么就固定的等待三秒之后再接着执行后面的操作。

封装方法如下:

public static void wait(int second){

   try {

           Thread.sleep(second*3000);

   } catch (InterruptedException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

   }

}

优缺点:硬性等待使用简单,但由于不知道一个线程需要等待多久,时间设置小了不行,设置长了往往会造成时间的浪费,影响性能。

3.2隐式等待(ImplicitlyWait)

implicitlyWait()方法比sleep()方法智能,sleep()方法只能在一个固定的时间等待,而implicitlyWait()可以在一个时间范围内等待,称为隐式等待。

隐式等待,是设置的全局等待。设置等待时间,是对页面中的所有元素设置加载时间,如果元素不是马上就能定位成功就会在固定等待时长内不停去搜索元素,在设置时间内发现元素则执行后面操作,如果超出了设置的时间还没发现元素则抛出异常。隐式等待可以理解成在规定的时间范围内,浏览器在不停的刷新页面,直到找到相关元素或者时间结束。

隐式等待采用全部设置,也就是说,你所有的findElement方法都会隐式等待10s,java代码,采用方式如下:

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

----此方法针对执行脚本的所有对象,等待10秒

timeouts()---->驱动超时对象,该对象可以进行多种场景的等待超时设置,而implicitlyWait即为隐式等待,会在设置的时间内不停查找元素或超时

隐式等待一般是在driver初始化之后设置,只用设置一次,全局生效可用,只适用于找元素findElement方法,其它方法没有等待效果,找到元素后就停止了,如果找到元素的时间大于设置的时间,则报一个找不到元素的异常。

此处共有三个方法,分别为查找元素的等待超时时间、页面加载等待超时时间和js脚本运行超时时间,方法如下代码所示:

System.setProperty("webdriver.chrome.driver", "D:\\test\\driver\\chromedriver.exe");

ChromeDriver chrome = new ChromeDriver();

//此处为设定页面加载超时时间为30s

chrome.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);

//此处为设定元素查找最长超时时间为10s

chrome.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

//此处为设置js脚本运行超时时间为30s

chrome.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);

优缺点:隐式等待相对灵活,但是设置是针对全局的,并不是所有的元素都需要等待,也不能适用条件更复杂的情况,如元素肉眼不可点击,元素不可见时不能用

3.3显式等待(Explicit wait)

显示等待是等待指定元素设置的等待时间,在设置时间内,默认每隔0.5s检测一次当前的页面这个元素是否存在,如果在规定的时间内找到了元素则执行相关操作,如果超过设置时间检测不到则抛出异常。默认抛出异常为:NoSuchElementException。做自动化的时候推荐使用显示等待。

显式等待的意思,就是判断这个元素是否加载完成,如果在规定的时间加载完成就进行下一步操作,如果在规定的时间没有加载完成就抛出异常。显式等待通常是自定义的一段代码,用来等待某个条件发生后再继续执行后续代码。此种方式用于特定元素、特定条件的等待,使用灵活,建议使用这种方法来进行等待设置。

【场景1:登录一个网站,输入用户名和密码后,点击登录,需要加载好几秒钟才能进入用户中心。例如你登录你网银,用户名和密码验证通过后,它需要等几秒,才能显示你账户信息,这几秒,它需要去数据库查询数据并显示在前端。

场景2:你登录一个旅行网站,填好了出发起点和目的地,点击搜索,需要查询等待几秒,然后给你显示车票信息。】

例子1:自带的条件

显式等待每隔一段时间扫描一次页面,检查元素是否满足结果条件,检查元素是否存在,不存在则继续等待,直到找到或超时, 该方式不是全局设置 ,推荐使用

当页面的某些元素需要鼠标放上去才展示出来时,显示等待的presenceoOfElementLocatde方法相当隐式等待,不可直接点击,需要配合鼠标操作才可点击

例2:自定义条件

自定义条件需要自定义我们需要等待的条件

4.实战

前边文章中都用到过强制和隐式等待了,没有用到过显示等待,那么宏哥就在这里给小伙伴后者童鞋们来演示一下,以便更好的区分和理解。

实例:打开百度首页面“更多”下拉页面里的音乐页面。

4.1测试用例

1.具体测试用例:

(1)打开百度首页

(2)鼠标移动到首页的“更多”

(3)等待出现“查看百度全部产品”

(4)定位音乐图标并点击

(5)获取新打开页面的title,进行断言

4.2代码设计

根据测试用例进行代码设计如下图所示:

4.3参考代码

参考代码如下:

package lessons;


import junit.framework.Assert;


import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.chrome.ChromeDriver;

import org.openqa.selenium.interactions.Actions;

import org.openqa.selenium.support.ui.ExpectedConditions;

import org.openqa.selenium.support.ui.WebDriverWait;


/**

* @author 北京-宏哥

*

* 《手把手教你》系列技巧篇(二十一)-java+ selenium自动化测试-三大延时等待(详细教程)

*

* 2021年8月18日

*/

public class TestMusic {

   

   @SuppressWarnings("deprecation")

   public  static  void  main(String [] args) throws InterruptedException {

       

       System.setProperty("webdriver.gecko.driver", ".\\Tools\\chromedriver.exe"); //指定驱动路径

 

       WebDriver driver = new ChromeDriver ();

       //最大化窗口  

       //driver.manage().window().maximize();  

       //打开百度首页

       driver.get("http://wwww.baidu.com");

       //声明一个Action对象

       Actions action=new Actions(driver);

       //鼠标移动到  更多产品 上

       action.moveToElement(driver.findElement(By.xpath("//a[text()='更多']"))).perform();

       //显示等待时间10s 等   全部产品>>  出现

       WebDriverWait w=new WebDriverWait(driver,10);

       w.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath("//a[text()='查看全部百度产品 >']")));

       //等待的元素出现后点击  音乐  

       WebElement cp=driver.findElement(By.xpath("//a/div[text()='音乐']"));

       cp.click();

       //断言音乐页面的Title值为   千千音乐-听见世界

       Assert.assertEquals("千千音乐-听见世界",driver.getTitle());

       System.out.println("断言通过!");      

   }

}

4.4运行代码

1.运行代码,右键Run AS->java Application,控制台输出,如下图所示:

2.运行代码后电脑端的浏览器的动作,如下小视频所示:

3.浏览器实现结果,宏哥怕大家不注意视频后浏览器实现结果,因此专门截图,如下图所示:

 

通过浏览器的实现结果,和代码的运行结果,可以判断出:即使web页面已跳转至新窗口,但是代码逻辑还在原有窗口

为解决该问题,我们需要引入 句柄 的概念:窗口句柄 ,粗略的理解,每个窗口对应一个句柄,句柄可认为是一个唯一长字符串

有了前边宏哥上下两卷的窗口切换的介绍,想必你知道这是怎么回事了吧,那么解决此问题的方法就是不是相当简单了,只需要切换一下窗口,进行断言即可!

4.5优化后的参考代码

package lessons;


import junit.framework.Assert;


import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.chrome.ChromeDriver;

import org.openqa.selenium.interactions.Actions;

import org.openqa.selenium.support.ui.ExpectedConditions;

import org.openqa.selenium.support.ui.WebDriverWait;


/**

* @author 北京-宏哥

*

* 《手把手教你》系列技巧篇(二十四)-java+ selenium自动化测试-三大延时等待(详细教程)

*

* 2021年8月28日

*/

public class TestMusic {

   

   

   public  static  void  main(String [] args) throws InterruptedException {

       

       System.setProperty("webdriver.gecko.driver", ".\\Tools\\chromedriver.exe"); //指定驱动路径

 

       WebDriver driver = new ChromeDriver ();

       //最大化窗口  

       driver.manage().window().maximize();  

       //打开百度首页

       driver.get("http://wwww.baidu.com");

       //声明一个Action对象

       Actions action=new Actions(driver);

       //鼠标移动到  更多产品 上

       action.moveToElement(driver.findElement(By.xpath("//a[text()='更多']"))).perform();

       //显示等待时间10s 等   全部产品>>  出现

       WebDriverWait w=new WebDriverWait(driver,10);

       w.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath("//a[text()='查看全部百度产品 >']")));

       //等待的元素出现后点击  音乐  

       WebElement cp=driver.findElement(By.xpath("//a/div[text()='音乐']"));

       cp.click();

       //切换至新窗口

       //首先,我们要先获取到一个主句柄,作为灯塔,防止"迷路"

       String mainWindow = driver.getWindowHandle();


       //接着我们要获取所有的句柄信息,并赋值给 handles

       //String[] handles=new String[driver.getWindowHandles().size()];

       //String handles = driver.getWindowHandles();

       System.out.println("切换前的title:"+driver.getTitle());

       //使用for循环,遍历所有的handles,以便判断

       for (String temphandle:driver.getWindowHandles()){

           if(!temphandle.equals(mainWindow))

               driver.close();

               driver.switchTo().window(temphandle);

       }

       //让我们打印一下当前窗口的 title

       System.out.println("切换后的title:"+driver.getTitle());

       //断言音乐页面的Title值为   千千音乐-听见世界

       Assert.assertEquals("千千音乐-听见世界",driver.getTitle());

       System.out.println("断言通过!");      

   }

}

4.6优化后代码运行

1.运行代码,右键Run AS->java Application,控制台输出,如下图所示:

2.运行代码后电脑端的浏览器的动作,如下小视频所示:

 

5.小结

1.三种等待方式比较起来,显示等待花费的时间最短,也最灵活,所以在自动化测试中可以提高效率。比较推荐使用显示等待。

2.隐形等待是设置了一个最长等待时间,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间截止,然后执行下一步。注意这里有一个弊端,那就是程序会一直等待整个页面加载完成,也就是一般情况下你看到浏览器标签栏那个小圈不再转,才会执行下一步,但有时候页面想要的元素早就在加载完成了,但是因为个别js之类的东西特别慢,我仍得等到页面全部完成才能执行下一步,我想等我要的元素出来之后就下一步怎么办?有办法,这就要看selenium提供的另一种等待方式——显性等待wait了。

需要特别说明的是:隐性等待对整个driver的周期都起作用,所以只要设置一次即可,我曾看到有人把隐性等待当成了sleep在用,走哪儿都来一下…其实来一下,和你走哪儿都来一下的效果是一样的。

3.不要混合隐式和显式等待。这样做可能会导致不可预测的等待时间。例如,设置 10 秒的隐式等待和 15 秒的显式等待可能会导致在 20 秒后发生超时。

6.拓展

实战中可能会遇到的问题:

代码中:the import org.junit.Assert.* cannot be revolved

具体解决方法:

右键单击项目名,选择buildpath->add library,弹出配置对话框

选择junit,next下一步


每天学习一点,今后必成大神-

往期推荐(由于跳转参数丢失了,所有建议选中要访问的右键,在新标签页中打开链接即可访问):

Appium自动化系列,耗时80天打造的从搭建环境到实际应用精品教程测试

Python接口自动化测试教程,熬夜87天整理出这一份上万字的超全学习指南

Python+Selenium自动化系列,通宵700天从无到有搭建一个自动化测试框架

Java+Selenium自动化系列,仿照Python趁热打铁呕心沥血317天搭建价值好几K的自动化测试框架

Jmeter工具从基础->进阶->高级,费时2年多整理出这一份全网超详细的入门到精通教程

Fiddler工具从基础->进阶->高级,费时100多天吐血整理出这一份全网超详细的入门到精通教程

Pycharm工具基础使用教程

相关文章
|
12天前
|
数据采集 测试技术 Python
自动化淘宝秒杀:使用Selenium WebDriver的实战指南
本文详细介绍了如何利用Selenium WebDriver自动化淘宝秒杀操作,包括环境配置、代码实现及注意事项,旨在帮助读者提升秒杀成功率,同时提醒合理使用以遵守平台规则。
58 8
|
2月前
|
Web App开发 前端开发 JavaScript
探索Python科学计算的边界:利用Selenium进行Web应用性能测试与优化
【10月更文挑战第6天】随着互联网技术的发展,Web应用程序已经成为人们日常生活和工作中不可或缺的一部分。这些应用不仅需要提供丰富的功能,还必须具备良好的性能表现以保证用户体验。性能测试是确保Web应用能够快速响应用户请求并处理大量并发访问的关键步骤之一。本文将探讨如何使用Python结合Selenium来进行Web应用的性能测试,并通过实际代码示例展示如何识别瓶颈及优化应用。
127 5
|
2月前
|
数据采集 存储 JavaScript
自动化数据处理:使用Selenium与Excel打造的数据爬取管道
本文介绍了一种使用Selenium和Excel结合代理IP技术从WIPO品牌数据库(branddb.wipo.int)自动化爬取专利信息的方法。通过Selenium模拟用户操作,处理JavaScript动态加载页面,利用代理IP避免IP封禁,确保数据爬取稳定性和隐私性。爬取的数据将存储在Excel中,便于后续分析。此外,文章还详细介绍了Selenium的基本设置、代理IP配置及使用技巧,并探讨了未来可能采用的更多防反爬策略,以提升爬虫效率和稳定性。
100 4
|
2月前
|
Java 测试技术 C#
自动化测试之美:从Selenium到Appium
【10月更文挑战第3天】在软件开发的海洋中,自动化测试如同一艘航船,引领着质量保证的方向。本文将带你领略自动化测试的魅力,从Web端的Selenium到移动端的Appium,我们将一探究竟,看看这些工具如何帮助我们高效地进行软件测试。你将了解到,自动化测试不仅仅是技术的展示,更是一种提升开发效率和产品质量的智慧选择。让我们一起启航,探索自动化测试的世界!
|
23天前
|
缓存 测试技术 Apache
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
38 1
|
2月前
|
自然语言处理 机器人 Python
ChatGPT使用学习:ChatPaper安装到测试详细教程(一文包会)
ChatPaper是一个基于文本生成技术的智能研究论文工具,能够根据用户输入进行智能回复和互动。它支持快速下载、阅读论文,并通过分析论文的关键信息帮助用户判断是否需要深入了解。用户可以通过命令行或网页界面操作,进行论文搜索、下载、总结等。
52 1
ChatGPT使用学习:ChatPaper安装到测试详细教程(一文包会)
|
2月前
|
JavaScript 前端开发 测试技术
精通Selenium:从基础到高级的网页自动化测试策略
【10月更文挑战第6天】随着Web应用变得越来越复杂,手动进行功能和兼容性测试变得既耗时又容易出错。自动化测试因此成为了现代软件开发不可或缺的一部分。Selenium是一个强大的工具集,它支持多种编程语言(包括Python),允许开发者编写脚本来模拟用户与Web页面的交互。本文将带领读者从Selenium的基础知识出发,逐步深入到高级的应用场景,通过丰富的代码示例来展示如何高效地进行网页自动化测试。
378 5
|
2月前
|
数据采集 Web App开发 数据可视化
Python爬虫教程:Selenium可视化爬虫的快速入门
Python爬虫教程:Selenium可视化爬虫的快速入门
|
26天前
|
Web App开发 设计模式 JavaScript
自动化测试之美:如何利用Selenium实现Web应用的高效测试
【10月更文挑战第29天】在软件开发的世界中,测试是确保产品质量的关键步骤。本文将带你了解如何使用Selenium这一强大的自动化测试工具,提高Web应用测试的效率和准确性。通过实际案例,我们将探索Selenium的核心功能及其在现代软件开发中的应用,旨在帮助读者掌握自动化测试的精髓,从而提升软件测试工作的整体效能。
29 0
|
2月前
|
Web App开发 缓存 Linux
高效Selenium测试技巧:轻松控制已开启的浏览器
【10月更文挑战第13天】在进行Selenium测试时,通常会启动新浏览器实例,但有时需要控制已开启的浏览器,以节省时间并更真实地模拟用户行为。这可通过设置Chrome为可远程控制并使用`Remote WebDriver`连接实现。需在启动Chrome时添加`--remote-debugging-port`参数,并通过Python脚本中的`webdriver.Remote`连接至指定端口。此外,还可利用会话ID(Session ID)重新连接浏览器,提高测试灵活性。需要注意浏览器版本兼容性及元素定位稳定性等问题,确保测试准确性和一致性。
316 1