Selenium 等待方式


常用的等待方式有4种:

线程等待

利用线程设置固定等待时间,直接粗暴费时。

Thread.sleep(1000);  

隐式等待方式(Implicit Wait)

从该行代码起到webdriver退出,为期间的页面元素查找设置一个超时时间。在此时间段内,Selenium会不断地尝试查找该元素,超时失败后才抛出NoSuchElementException。当没有设置默认等待时,Selenium不会作任何等待。

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

显示等待方式(Explicit Wait)

就是在给定的等待时间之内,没有符合给定条件,就抛出TimeoutException。
另外,当调用isEnable(), isDisplayed(), isSelected()这些判定方法,然而元素不存在时,会抛出NoSuchElementExpception异常。

Step 1, 声明WebDriverWait变量

WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10)

Step 2, 使用ExpectedConditions中定义的条件设置等待条件。

wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("username")));
driver.findElement(By.id("username")).sendKeys("HelloWorld");

除使用ExpectedConditions内定义的条件外,还可以自定义条件:

WebElement element = (new WebDriverWait(webdriver, 10)).until(new ExpectedCondition<WebElement>() {
@Override
	public WebElement apply(WebDriver wd) {
		return
	wd.findElement(By.partialLinkText("www.seleniumhq.org/"));
	}
});

这里有一个疑问就是: apply这个函数是干嘛的?
apply函数继承自com.google.common.base.Function接口。接口定义:
http://www.boyunjian.com/javadoc/com.ning.billing/killbill-osgi-bundles-analytics/0.2.2/_/com/google/common/base/Function.html
里面写到,这个函数是把其实现应用到输入参数当中,并返回处理结果。这里而until函数来自FluentWait类,作用是重复应用该实例(这里指WebDriverWait)的输入值(WebDriver)到给定的函数(apply)直到满足条件、抛出异常的情况。


流畅等待 Fluent Wait

我们可以从下面的代码中看到,对每个流畅等待实例,我们可以设置最大等待时间、条件检查间隔、需要忽略的异常,当然还有等待条件。这个与显式等待非常相似。WebDriverWait继承了FluentWait<WebDriver>。FluentWait可以设置检查间隔,WebDriverWait更简便。

// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
 Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
     .withTimeout(30, SECONDS)
     .pollingEvery(5, SECONDS)
     .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
   public WebElement apply(WebDriver driver) {
     return driver.findElement(By.id("foo"));
   }
 });

隐式与显式等待的使用场合

不要混合用显式与隐式等待。因为隐式等待经常是在驱动端(如IEDriverServer.exe、ChromeDriver.exe等)和WebDriver server(selenium-server-standalone.jar)上实现的。而显式等待只在语言包(如selenium-java.jar)上实现。当把它们混合使用的时候,得到的是一种不确定的行为,而且这种行为还可能因为驱动端的改变而改变。当使用RemoteWebDriver或Grid的时候,情况会变得更加复杂。所以,当一个元素查找失败时,程序可能会因此遇到长期或一直等待的等情况。

参考文章:
https://stackoverflow.com/questions/15164742/combining-implicit-wait-and-explicit-wait-together-results-in-unexpected-wait-ti/15174978#15174978
官方文章也有相关警告:
http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp#explicit-and-implicit-waits

一篇更直接的。。。使用显式等待,忘记隐式等待的存在 LOL:
https://stackoverflow.com/questions/10404160/when-to-use-explicit-wait-vs-implicit-wait-in-selenium-webdriver
总结来讲就是:隐式等待功能有限(只能作用于等待元素),行为没有文档正式写明而且依赖于浏览器方的实现(也就是不可靠)。此文章中也有作者总结的使用情形:
Explicit wait:

  • 有文档说明的已定义的操作。
  • 运行在Selenium的本地部分(在你的代码里)。
  • 在任何你能想到的情况下。
  • 返回成功或timeout错误。
  • 定义元素不存在为成功条件时。
  • 自定义尝试间的等待时间和忽略的异常。

Implicit wait:

  • 没有文档说明的,特别是没有定义的行为。
  • 运行在Selenium远程端的部分(控制浏览器的部分)。
  • 只用在findElement方法。
  • 返回元素是否找到时。
  • 测试时如果找不到元素都必须等待直到超时时。
  • 不能被自定义时。

Tips

每个操作默认等待时间:5分钟
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值