Selenium WebDriver中的隐式、显式和流畅等待

在Selenium中,“等待”在执行测试中起着重要作用。在本教程中,将了解Selenium中隐式和显式等待的各个方面和区别。

在本教程中,将了解Selenium中不同类型的等待:

  • 为什么我们需要Selenium的等待?
  • 隐式等待
  • 显式等待
  • 流畅的等待
  • 隐式等待与显式等待之间的差异

为什么我们需要Selenium的等待?

大多数Web应用程序都是使用AJAX和Javascript开发的。当浏览器加载页面时,我们希望与之交互的元素可能会以不同的时间间隔加载。

这不仅使标识元素变得困难,而且如果找不到元素,它将抛出“ElementNotVisibleException”异常。使用Selenium Waits,我们可以解决这个问题。

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

假设我们试图找到一个具有一些“预期条件”(显式等待)的元素,如果该元素不在显式 wait(10 Seconds) 定义的时间范围内,则在抛出“ElementNotVisibleException”之前,它将使用隐式等待(20秒)定义的时间范围。

Selenium Web驱动程序等待

  1. 隐式等待
  2. 显式等待

Selenium中的隐性等待

Selenium中的隐式等待用于告诉Web驱动程序在抛出“No That Element Exception”之前等待一定的时间。一旦我们设置了时间,Web驱动程序将在抛出异常之前等待该元素。

Selenium Web Driver借用了Watir的隐式等待的概念。

在下面的示例中,我们声明了时间范围为10秒的隐式等待。这意味着如果元素没有在该时间范围内位于网页上,它将抛出异常。

要在Selenium WebDriver中声明隐式等待,执行以下操作:

隐式等待语法:

driver.manage().timeouts().implicitlyWait(TimeOut, TimeUnit.SECONDS);
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 = "" ;
        // launch Chrome and redirect it to the Base URL
        driver.get("http://www.itxiaonv.com/test/guru99home/" );
        //Maximizes the browser window
        driver.manage().window().maximize() ;
        //get the actual value of the title
        aTitle = driver.getTitle();
        //compare the actual title with the expected title
        if (aTitle.equals(eTitle)) {
            System.out.println( "Test Passed") ;
        } else {
            System.out.println( "Test Failed" );
        }
        //close browser
        driver.close();
    }
}

在上面的示例中,

考虑以下代码:

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

隐式等待将接受两个参数,第一个参数将接受时间为整数值,第二个参数将接受以秒、分、毫秒、微秒、纳秒、天、小时等为单位的时间度量。

Selenium中的显式等待

Selenium中的显式等待用于告诉Web驱动程序在抛出“ElementNotVisibleException”异常之前等待某些条件(预期条件)或超过最大时间。在等待动态加载的Ajax元素时,它提供了比隐式等待更好的选择。

一旦我们声明显式等待,我们就必须使用“ExspectedConditions”,或者我们可以使用流畅的等待来配置我们想要检查条件的频率。这些天在实现时,我们一般都在使用 Thread.Sleep() ,不推荐使用

在下面的示例中,我们为“WebDriverWait”类创建引用等待,并使用“WebDriver”引用进行实例化,我们给出的最大时间范围为20秒。

显式等待语法:

WebDriverWait wait = new WebDriverWait(WebDriverRefrence,TimeOut);
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 = "" ;
        // launch Chrome and redirect it to the Base URL
        driver.get("http://www.itxiaonv.com/test/guru99home/" );
        //Maximizes the browser window
        driver.manage().window().maximize() ;
        //get the actual value of the title
        aTitle = driver.getTitle();
        //compare the actual title with the expected title
        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();
    }
 
}

考虑以下代码:

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();

在此WebDriver等待示例中,等待“WebDriverWait”类或“ExspectedConditions”中定义的时间量(以最先发生的那个为准)。

上面的Java代码声明,我们正在等待网页上的“WebDriverWait”类中定义的20秒的时间范围内的元素,直到满足“ExspectedConditions”并且条件是“visibilityof ElementLocated”。

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

  1. alertIsPresent()
  2. elementSelectionStateToBe()
  3. elementToBeClickable()
  4. elementToBeSelected()
  5. frameToBeAvaliableAndSwitchToIt()
  6. invisibilityOfTheElementLocated()
  7. invisibilityOfElementWithText()
  8. presenceOfAllElementsLocatedBy()
  9. presenceOfElementLocated()
  10. textToBePresentInElement()
  11. textToBePresentInElementLocated()
  12. textToBePresentInElementValue()
  13. titleIs()
  14. titleContains()
  15. visibilityOf()
  16. visibilityOfAllElements()
  17. visibilityOfAllElementsLocatedBy()
  18. visibilityOfElementLocated()

在Selenium中流畅地等待

Selenium中的流畅等待用于定义web驱动程序等待条件的最长时间,以及在抛出“ElementNotVisibleException”异常之前我们希望检查条件的频率。它定期检查Web元素,直到找到对象或发生超时。

频率:设置具有时间框架的重复周期,以便在固定的时间间隔验证/检查条件

让我们考虑一个场景,其中元素以不同的时间间隔加载。元素可能在10秒内加载。在这种情况下,流畅的等待是理想的等待,因为这将尝试以不同的频率查找元素,直到找到它或最终计时器用完。

等待语法:

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

上述代码在Selenium v3.11及更高版本中已弃用。需要使用

Wait wait = new FluentWait(WebDriver reference)
.withTimeout(Duration.ofSeconds(SECONDS))
.pollingEvery(Duration.ofSeconds(SECONDS))
.ignoring(Exception.class);
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();
        // launch Chrome and redirect it to the Base URL
        driver.get("http://www.itxiaonv.com/test/guru99home/" );
        //Maximizes the browser window
        driver.manage().window().maximize() ;
        //get the actual value of the title
        aTitle = driver.getTitle();
        //compare the actual title with the expected title
        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"));
            }
        });
        //click on the selenium link
        clickseleniumlink.click();
        //close~ browser
        driver.close() ;
    }
}

考虑以下代码:

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

在上面的示例中,我们通过忽略“NoSuchElementException”声明了一个超时为30秒的流畅等待,并将频率设置为5秒。

考虑以下代码:

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"));

我们已经创建了一个新函数来标识页面上的Web元素。(例如:这里的Web元素只是网页上的Selenium链接)。

频率设置为5秒,最长时间设置为30秒。因此,这意味着它将检查元素是否位于此时间范围内,如果元素位于此时间范围内,它将执行操作,否则将抛出“ElementNotVisibleException”

隐式等待与显式等待之间的差异

以下是Selenium中隐式等待和显式等待的主要区别:

隐式等待 显式等待
隐式等待时间应用于脚本中的所有元素 显式等待时间仅适用于我们预期的那些元素
在隐式等待中,我们不需要在要定位的元素上指定“ExspectedConditions 在显式等待中,我们需要在要定位的元素上指定“ExspectedConditions
建议在元素位于Selenium隐式等待中指定的时间范围内时使用 建议在加载元素的时间较长以及验证元素 like(visibilityOfElementLocated, elementToBeClickable,elementToBeSelected) 的属性时使用

结论:

隐性等待、显性等待和流畅等待是Selenium中使用的不同等待。这些等待的用法是始终不建议在以下情况下使用 Thread.Sleep() 测试我们的应用程序或构建我们的框架。

IT赶路人

专注IT知识分享