Selenium+java - 中常见等待的几种形式
前言
在自动化测试中,我们经常会碰到编写脚本过程中操作某个元素的时候, 需要等待页面加载完成后,才能对元素操作,否则会报错,提示页面元素不存在异常,我们需要等待元素加载完成后,
才能继续操作,而Selenium为我们提供了对应的等待方法,来判断元素是否存在。
下面将用一个例子,针对元素等待操作做逐一讲解
实际案例
场景:点击【创建div】按钮,3秒后,页面会出现一个绿色的div块,同时显示文字“我是div,我出现了,哈哈!”,我们需要代码去判断这个div是否存在, 然后高亮,并正常显示文字。
被测html代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>等待练习案例</title> </head> <style type="text/css"> #green_box { background-color: chartreuse; width: 400px; height: 200px; border: none; } </style> <script type="application/javascript"> function wait_show() { setTimeout("create_div()", 3000); } function create_div() { var divElement = document.createElement('div'); divElement.id = "green_box"; var pElement = document.createElement('p'); pElement.innerText = "我是div,我出现了,哈哈!"; document.body.appendChild(divElement); divElement.appendChild(pElement); } </script> <body> <button onclick="wait_show()">创建div</button> </body> </html>
1、强制等待
强制等待,就是硬等待,使用方法Thread.sleep(int sleeptime),使用该方法会让当前执行进程暂停一段时间(你设定的暂停时间)。弊端就是,你不能确定元素多久能加载完全,如果两秒元素加载出来了,你用了30秒,造成脚本执行时间上的浪费。
具体示例代码如下:
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class TestWaitDemo { WebDriver driver; @BeforeClass public void beforeClass(){ System.setProperty("webdriver.chrome.driver", "driver/chromedriver.exe"); driver = new ChromeDriver(); } @Test public void testByThread() { //打开测试页面 driver.get("file:///C:/Users/Administrator/Desktop/waitDemo.html"); driver.manage().window().maximize(); driver.findElement(By.id("wait")).click(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } //获得div块级元素 WebElement element = driver.findElement(By.id("green_box")); //获取该元素css样式中background-color属性值 String cssValue = element.getCssValue("background-color"); //输出属性值 System.out.println("cssValue: "+cssValue); } @AfterClass public void afterClass(){ driver.quit(); } }
2、页面等待
有时候我们打开一个网页,网页本身加载速度就比较慢,只能等网页完全加载完毕,才能执行操作,那么就可以用pageLoadTimeout(pageLoadTime,TimeUnit.SECONDS)这个方法,如在设定时间内,网页还没有还没完全加载就会报错,剩下的时间将不再等待。
具体示例代码如下:
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import java.util.concurrent.TimeUnit; public class TestWaitDemo { WebDriver driver; @BeforeClass public void beforeClass(){ System.setProperty("webdriver.chrome.driver", "driver/chromedriver.exe"); driver = new ChromeDriver(); } @Test public void testByPageLoad() { //打开测试页面 driver.get("file:///C:/Users/Administrator/Desktop/waitDemo.html"); //设置等待时间为3秒,如果3秒页面没有全部加载出来,就会报错,如果小于3秒就全部加载出来了,剩下的时间将不再等待,继续下一步操作 driver.manage().timeouts().pageLoadTimeout(3, TimeUnit.SECONDS); driver.manage().window().maximize(); } @AfterClass public void afterClass(){ driver.quit(); } }
3、隐式等待
WebDriver 提供了三种隐性等待方法:
- implicitlyWait
识别对象时的超时时间。过了这个时间如果对象还没找到的话就会抛出NoSuchElement 异常。
- setScriptTimeout
异步脚本的超时时间。WebDriver 可以异步执行脚本,这个是设置异步执行脚本,脚本返回结果的超时时间。
- pageLoadTimeout
页面加载时的超时时间。因为 WebDriver 会等页面加载完毕再进行后面的操作,所以如果页面超过设置时间依然没有加载完成,那么 WebDriver 就会抛出异常。
隐式等待(implicit),方法implicitlyWait(long time, TimeUnit.SECONDS),即全局设置,对整个driver都有作用,如在设定时间内,特定元素没有加载完成,则抛出异常,如果元素加载完成,剩下的时间将不再等待。
具体示例代码如下:
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import java.util.concurrent.TimeUnit; public class TestWaitDemo { WebDriver driver; @BeforeClass public void beforeClass(){ System.setProperty("webdriver.chrome.driver", "driver/chromedriver.exe"); driver = new ChromeDriver(); } @Test public void testByImplicitlyWait() { //打开测试页面 driver.get("file:///C:/Users/Administrator/Desktop/waitDemo.html"); //设置等待时间为3秒,如果3秒元素没有加载出来,就会报错,如果小于3秒元素加载出来了,剩下的时间将不再等待,继续下一步操作 driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS); driver.manage().window().maximize(); driver.findElement(By.id("wait")).click(); //获得div块级元素 WebElement element = driver.findElement(By.id("green_box")); //获取该元素css样式中background-color属性值 String cssValue = element.getCssValue("background-color"); //输出属性值 System.out.println("cssValue: "+cssValue); } @AfterClass public void afterClass(){ driver.quit(); } }
4、显式等待
显示等待,就是明确的要等到某个元素的出现或者是某个元素的可点击等条件等到为止,才会继续执行后续操作,等不到,就一直等,除非在规定的时间之内都没找到,那么就抛出异常了
方法一:
具体代码如下:
package com.brower.demo; 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.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class TestWaitDemo { WebDriver driver; @BeforeClass public void beforeClass() { System.setProperty("webdriver.chrome.driver", "driver/chromedriver.exe"); driver = new ChromeDriver(); } @Test public void testByShowWaiting() { //打开测试页面 driver.get("file:///C:/Users/Administrator/Desktop/waitDemo.html"); driver.manage().window().maximize(); driver.findElement(By.id("wait")).click(); /** *等待时间为3秒,WebDriverWait默认每500ms就调用一次ExpectedCondition直到定位到div,如果3秒内div显示出来,则继续下一步, * 如果超过3秒没有显示出来,那么则until()会抛出org.openqa.selenium.TimeoutExceptionn异常 */ WebDriverWait wait = new WebDriverWait(driver, 3); //元素是否存在,如果超过设置时间检测不到则抛出异常。 wait.until(new ExpectedCondition<WebElement>() { @Override public WebElement apply(WebDriver driver) {
//重写方法 return driver.findElement(By.id("green_box")); } }); //获得div块级元素 WebElement element = driver.findElement(By.id("green_box")); //获取该元素css样式中background-color属性值 String cssValue = element.getCssValue("background-color"); //输出属性值 System.out.println("cssValue: " + cssValue); } @AfterClass public void afterClass() { driver.quit(); } }
方法二
示例代码如下:
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.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class TestWaitDemo { WebDriver driver; @BeforeClass public void beforeClass() { System.setProperty("webdriver.chrome.driver", "driver/chromedriver.exe"); driver = new ChromeDriver(); } @Test public void testByShowWaiting() { //打开测试页面 driver.get("file:///C:/Users/Administrator/Desktop/waitDemo.html"); driver.manage().window().maximize(); driver.findElement(By.id("wait")).click(); /** *等待时间为3秒,WebDriverWait默认每500ms就调用一次ExpectedCondition直到定位到div,如果3秒内div显示出来,则继续下一步, * 如果超过3秒没有显示出来,那么则until()会抛出org.openqa.selenium.TimeoutExceptionn异常 */ WebDriverWait wait = new WebDriverWait(driver, 3); wait.until(ExpectedConditions.presenceOfElementLocated(By.id("green_box"))); //获得div块级元素 WebElement element = driver.findElement(By.id("green_box")); //获取该元素css样式中background-color属性值 String cssValue = element.getCssValue("background-color"); //输出属性值 System.out.println("cssValue: " + cssValue); } @AfterClass public void afterClass() { driver.quit(); } }
显式等待使用ExpectedConditions类中自带方法, 可以进行显式等待的判断,常用的判断条件如下表:
等待的条件方法名称 | 描述 |
elementToBeClickable(By locator) | 页面元素是否在页面上可用和可被单击 |
elementToBeSelected(WebElement element) | 页面元素处于被选中状态 |
presenceOfElementLocated(By locator) | 页面元素在页面中存在 |
textToBePresentInElement(By locator) | 在页面元素中是否包含特定的文本 |
textToBePresentInElementValue(By locator, java.lang.String text) | 页面元素值 |
titleContains(java.lang.String title) | 标题 (title) |
显式等待常跟以下三种方法一起使用,用来判断元素
- isEnable() 检查元素是否被启用
- isSelected() 检查元素是否被选中
- isDisplay() 检查元素是否可见
运行结果
优秀不够,你是否无可替代
软件测试交流QQ群:721256703,期待你的加入!!
欢迎关注我的微信公众号:软件测试君
![](https://www.cnblogs.com/images/cnblogs_com/longronglang/1061549/o_QQ%E6%88%AA%E5%9B%BE20190728134401.jpg)