5-Selenium WebDriver三种等待--隐式等待-显式等待和流畅等待

在selenium中,Waits在执行测试中扮演重要角色。在本教程中,您将学习Selenium中“隐式”和“显式”等待的各个方面。


在Selenium中为什么需要等待?

在现在很多软件产品为了加强前端的效果,采取了大量的AJAX、Javascript 和Jquery技术,很多窗体内的数据,需要等待一会,才能加载完数据,才能出现一些元素,driver才能操作这些元素做一些事情。

还有就是我们做一些操作,本身可能也需要等待一会才有数据显示。所以在自动化脚本开发过程,合理的设置时间等待是非常必要的,可以说百分之90以上的自动化测试用例执行失败,基本上是很时间等待有关系,造成元素没有及时在界面上显示,而报no such element子类的错误

 

让我们假设一个场景,我们必须在测试中同时使用隐含等待和显式等待。假设隐含等待时间设置为 20 秒,显式等待时间设置为 10 秒。

 

假设我们正试图找到一种元素,它有一些“ExpectedConditions”(显式等),如果不在显示等待(10秒)内, 它将使用隐式定义的时间等待(20秒)之前抛出“ElementNotVisibleException”。

假设我们试图找到一个具有一些 “ExpectedConditions” (显式等待) 的元素,如果该元素不在显式等待 (10 秒) 定义的时间范围内, 它将使用隐式等待 (20 秒) 定义的时间框架,然后抛出一个 “ElementNotVisibleException”。

Selenium提供的3种等待

1. Implicit Wait(模糊/隐式等待)

Selenium Web Driver借鉴了Watir(基于网页模式的自动化功能测试工具Web application testing in ruby)中的隐式等待概念。

隐式等待,是对整个页面元素操作有效,会先设置等待时间,一直等待所有页面内容加载完成,直到超时再抛出异常。

缺点:使用隐式等待,程序会一直等到整个页面加载完成才会执行下一步操作
 

需要导入一下Jar包

import java.util.concurrent.TimeUnit;

语法:

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

从这个命令可以看出,这个等待是针对driver的,它会应用到所有元素的等待,对整个Driver周期起作用,只需要设置一次即可。

参数

隐式等待将接受2个参数,第一个参数将接受时间作为整数值,第二个参数将接受时间度量ECONDS, MINUTES, MILISECOND, MICROSECONDS, NANOSECONDS, DAYS, HOURS等等。

 

在下面的例子中,我们已经声明了一个隐式等待,时间为 10 秒。这意味着,如果元素在10秒内没有出现,它将抛出异常。

package guru.test99;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;
public class AppTest {
 
  protected WebDriver driver;
  @Test
  public void guru99tutorials() throws InterruptedException {
  System.setProperty ("webdriver.chrome.driver",".\\chromedriver.exe" );
  driver = new ChromeDriver();  
  driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS) ;
  String eTitle = "Demo Guru99 Page";
  String aTitle = "" ;
  // 启动Chrome并将其重定向到基本URL
  driver.get("http://demo.guru99.com/test/guru99home/" );
  // 最大化浏览器窗口
  driver.manage().window().maximize() ;
  //获取标题的实际值
  aTitle = driver.getTitle();
  //将实际标题与预期标题进行比较
  if (aTitle.equals(eTitle)){
    System.out.println( "Test Passed") ;
  }else {
    System.out.println( "Test Failed" );
  }
  //关闭浏览器
  driver.close();
}
}

 

2. Explicit Wait (显式/明确等待)

显示等待使用WebDriverWait和ExpectedCondition类完成。

显式等待用于告诉 Web driver等待某些条件 (Expected Conditions预期条件) 或超过的最长时间,然后抛出 element entnot visibleexception异常。

显式等待是一种智能的等待,但是它只能应用于等待指定的元素加载完成。显式等待提供了比隐式等待更好的选项,因为它将动态等待加载的 Ajax 元素。

一旦我们声明了显式的Wait,我们就必须使用ExpectedCondtions,或者我们可以配置使用Fluent wait检查条件的频率。现在,在实现时我们使用Thread.Sleep(),一般不建议使用。

在下面的例子中,我们正在为“WebDriverWait”类创建引用wait,并使用“WebDriver”引用实例化它,我们给出了一个20秒的最大时间框架。

语法:

WebDriverWait wait = new WebDriverWait(WebDriverRefrence,TimeOut);

WebDriverWait wait =new WebDriverWait(driver, 20)

wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( "/html/body/div[1]/i")));

 

package guru.test99;

import java.util.concurrent.TimeUnit;
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.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;

public class AppTest2 {
  protected WebDriver driver;
  @Test
  public void guru99tutorials() throws InterruptedException {
  System.setProperty ("webdriver.chrome.driver",".\\chromedriver.exe" );
  driver = new ChromeDriver(); 
  WebDriverWait wait=new WebDriverWait(driver, 20);
  String eTitle = "Demo Guru99 Page";
  String aTitle = "" ;
  // 启动Chrome并将其重定向到基本URL
  driver.get("http://demo.guru99.com/test/guru99home/" );
  //最大化浏览器窗口
  driver.manage().window().maximize() ;
  //获取标题的实际值
  aTitle = driver.getTitle();
  //将实际标题与预期标题进行比较
  if (aTitle.contentEquals(eTitle)){
    System.out.println( "Test Passed") ;
  }else {
    System.out.println( "Test Failed" );
  }
  WebElement guru99seleniumlink;
  guru99seleniumlink= wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( "/html/body/div[1]/section/div[2]/div/div[1]/div/div[1]/div/div/div/div[2]/div[2]/div/div/div/div/div[1]/div/div/a/i")));
  guru99seleniumlink.click();
  }
}

 

以下是可以在显式等待中使用的预期条件:

  • alertIsPresent()
  • elementSelectionStateToBe()
  • elementToBeClickable()
  • elementToBeSelected()
  • frameToBeAvaliableAndSwitchToIt()
  • invisibilityOfTheElementLocated()
  • invisibilityOfElementWithText()
  • presenceOfAllElementsLocatedBy()
  • presenceOfElementLocated()
  • textToBePresentInElement()
  • textToBePresentInElementLocated()
  • textToBePresentInElementValue()
  • titleIs()
  • titleContains()
  • visibilityOf()
  • visibilityOfAllElements()
  • visibilityOfAllElementsLocatedBy()
  • visibilityOfElementLocated()

 

3.Fluent Wait (流畅等待)

流畅等待被用来告诉 Web driver等待一个条件,以及我们想在抛出 “element entnot visibleexception” 异常之前检查这个条件的频率。

频率Frequency: 设置一个最大等待实践,而且可以设置固定的时间间隔去验证/检查特定的条件。

让我们考虑一个场景,其中一个元素在不同的时间间隔加载。如果我们显式地声明等待20秒,则元素可能在20秒、10秒甚至更短的时间内加载,它将等到指定的时间才进行下一步操作或者抛出异常。在这种情况下,流畅等待是理想的等待,因为它将尝试以不同的频率查找元素,只要找到元素即可。

语法

Wait wait = new FluentWait(WebDriver reference) .withTimeout(timeout, SECONDS) .pollingEvery(timeout, SECONDS) .ignoring(Exception.class);

所谓流畅,是指可以设置轮循检查Element的频率。

package guru.test99;

import org.testng.annotations.Test;
import java.util.NoSuchElementException;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

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.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;

public class AppTest3 {
  protected WebDriver driver;
  @Test
  public void guru99tutorials() throws InterruptedException 
  {
  System.setProperty ("webdriver.chrome.driver",".\\chromedriver.exe" );
  String eTitle = "Demo Guru99 Page";
  String aTitle = "" ;
  driver = new ChromeDriver();
  // 启动Chrome并将其重定向到基本URL
  driver.get("http://demo.guru99.com/test/guru99home/" );
  //最大化浏览器窗口
  driver.manage().window().maximize() ;
  //获取标题的实际值
  aTitle = driver.getTitle();
  //将实际标题与预期标题进行比较
  if (aTitle.contentEquals(eTitle))
  {
  System.out.println( "Test Passed") ;
  }
  else {
  System.out.println( "Test Failed" );
    }
  
  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)              
      .withTimeout(30, TimeUnit.SECONDS)      
      .pollingEvery(5, TimeUnit.SECONDS)      
      .ignoring(NoSuchElementException.class);
  WebElement clickseleniumlink = wait.until(new Function<WebDriver, WebElement>(){
  
    public WebElement apply(WebDriver driver ) {
      return driver.findElement(By.xpath("/html/body/div[1]/section/div[2]/div/div[1]/div/div[1]/div/div/div/div[2]/div[2]/div/div/div/div/div[1]/div/div/a/i"));
    }
  });
  //单击selenium链接
  clickseleniumlink.click();
  //关闭浏览器
  driver.close() ;
  }
}

 

解读:

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)              
  .withTimeout(30, TimeUnit.SECONDS)      
  .pollingEvery(5, TimeUnit.SECONDS)      
  .ignoring(NoSuchElementException.class);

在上面的例子中,我们声明了一个流畅的等待,超时时间为30秒,并且忽略NoSuchElementException,将频率设置为5秒

 

隐式等待和显式等待的区别:

隐式等待 Implicit Wait

显示等待 Explicit Wait

隐式等待时间应用于脚本中的所有元素

显式等待时间只应用于指定等待的元素

我们不需要在要定位的元素上指定ExpectedConditions

我们需要在要定位的元素上指定ExpectedConditions

建议在元素的出现时间小于隐式等待中指定的时间范围时使用

建议在元素加载时间较长时使用,也可以用于验证元素的属性,如(visibilityofelementlocate, elementToBeClickable, elementtobesselected)

总结:

隐式、显式和流畅等待是selenium中使用的不同等待。这些等待的使用完全基于在不同时间间隔加载的元素。在测试应用程序或构建框架时,通常不建议使用Thread.Sleep()。

 

参考:
Java+Selenium3方法篇41-FluentWait  - CSDN博客

发布了69 篇原创文章 · 获赞 117 · 访问量 19万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 成长之路 设计师: Amelia_0503

分享到微信朋友圈

×

扫一扫,手机浏览