Selenium 等待——语法的隐式和显式


In Selenium, “等待” 在执行测试中起着重要作用。在本教程中,您将学习隐式等待和显式等待的各个方面以及它们之间的区别 Selenium.

为什么我们需要等待 Selenium?

大多数 Web 应用程序都是使用 阿贾克斯Javascript。当浏览器加载页面时,我们想要交互的元素可能会在不同的时间间隔加载。

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

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

假设我们试图找到一个元素,它有一些 “预期条件 “(显式等待),如果元素不在显式等待(10 秒)定义的时间范围内,它将使用隐式等待(20 秒)定义的时间范围,然后抛出“元素不可见异常“。

Selenium Web 驱动程序等待

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

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

隐式等待 Selenium

这个 隐式等待 Selenium 用于告诉 Web 驱动程序在抛出“无此类元素异常”之前等待一段时间。默认设置为 0。一旦我们设置了时间,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("https://demo.guru99.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) ;

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

明确等待 Selenium

这个 明确等待 Selenium 用于告诉 Web 驱动程序等待某些条件(预期条件)或超过最大时间,否则抛出“ElementNotVisibleException”异常。这是一种智能等待,但只能应用于指定元素。它比隐式等待提供了更好的选择,因为它等待动态加载的 Ajax 元素。

一旦我们声明了显式等待,我们就必须使用“预期条件“或者我们可以配置检查条件的频率 流利的等待. 这些天我们在实施过程中使用 线程.Sleep() 一般不建议使用

在下面的例子中,我们创建了引用等待“网络驱动程序等待”类并使用“实例化网络驱动程序”参考,我们给出的最大时间范围是 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("https://demo.guru99.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 等待示例中,等待“网络驱动程序等待”类或“预期条件”以先发生者为准。

以上 Java 代码表明我们正在等待元素的 20 秒时间范围,如“网络驱动程序等待”类,直到“预期条件” 满足且条件为“元素定位的可见性“。

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

  1. 警报是否存在()
  2. 元素选择状态要成为()
  3. 可点击元素()
  4. 要选择的元素()
  5. 帧可用并切换到它()
  6. 元素位置的不可见性()
  7. 元素与文本的不可见性()
  8. presenceOfAllElementsLocatedBy()
  9. presenceOfElementLocated()
  10. 元素中要出现的文本()
  11. 元素定位中出现的文本()
  12. 元素值中要出现的文本()
  13. 标题是()
  14. 标题包含()
  15. 可见性()
  16. 可见性所有元素 ()
  17. 可见性所有元素定位于 ()
  18. 元素定位可见性()

流畅等待 Selenium

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

频率: 设置时间框架的重复周期,以定期的时间间隔验证/检查状况

让我们考虑一个元素以不同时间间隔加载的场景。如果我们声明显式等待 10 秒,元素可能会在 20 秒、20 秒甚至更长时间内加载。它会等到指定的时间后再抛出异常。在这种情况下,流畅等待是理想的等待方式,因为它会尝试以不同的频率查找元素,直到找到它或最终计时器用完。

Fluent Wait 语法:

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("https://demo.guru99.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);				

在上面的例子中,我们声明了一个流畅的等待,超时时间为 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 秒。因此,这意味着它将每 5 秒检查一次网页上的元素,最大时间为 30 秒。如果元素位于此时间范围内,它将执行操作,否则它将抛出“元素不可见异常

还检查: - Selenium IDE 初学者教程

隐式等待与显式等待之间的区别

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

隐式等待 显式等待
隐式等待时间适用于脚本中的所有元素 明确等待时间仅适用于我们预期的元素
在隐式等待中,我们需要 而不去 在要定位的元素上指定“ExpectedConditions” 在显式等待中,我们需要在要定位的元素上指定“预期条件”
建议在元素位于指定的时间范围内时使用 Selenium 隐式等待 建议在元素需要很长时间加载时使用,并用于验证元素的属性,如(visibilityOfElementLocated、elementToBeClickable、elementToBeSelected)

结语

隐式、显式和流畅等待是 Selenium。这些等待的使用完全基于在不同时间间隔加载的元素。始终不建议在以下情况下使用 Thread.Sleep() 测试与验证 我们的应用程序或构建我们的框架。

还检查: - Selenium 初学者教程:7 天学会 WebDriver