隐式 vs 显式 vs Fluent 等待

Posted

技术标签:

【中文标题】隐式 vs 显式 vs Fluent 等待【英文标题】:Implicit vs Explicit vs Fluent Wait 【发布时间】:2018-06-17 03:01:14 【问题描述】:

Implicit、Explicit、Fluent Wait 有什么区别?

如果我们在隐式等待中设置 10 秒并且在 10 秒之前,则在 3 秒内只有元素被定位。

那个时候会发生什么?它将等待 10 秒或继续进行。

【问题讨论】:

显式等待的相同问题,如果我在时间之前完全满足了预期条件。到时候会继续还是等待提时间? 在此处发布问题之前请先谷歌答案,如果您有具体疑问,请更新问题。 【参考方案1】:

隐式等待将告诉 Web 驱动程序在抛出“NoSuchElementException”之前等待一定的时间。默认设置为 0。一旦我们设置了时间,Web 驱动程序将在抛出异常之前等待该时间。如果您给定了 10 秒作为等待时间,但在 3 秒时识别出元素,则它将在 3 秒后进入下一步。

显式等待是您定义的代码,用于等待特定条件发生,然后再继续执行代码。显式等待将告诉 Web 驱动程序在抛出 NoSuchElementException 异常之前等待某些条件,例如 visibilityOfElementLocated 和最长时间。你可以参考这个-https://configureselenium.blogspot.com/2019/07/implicit-explicit-fluent-wait-in.html

【讨论】:

【参考方案2】:

隐式等待

ImplicitWait 是配置WebDriver 实例的实现,即驱动程序 在一定时间内轮询HTML DOM(NANOSECONDSMICROSECONDS、@ 987654341@、SECONDSMINUTESHOURSDAYS) 尝试查找一个或多个元素(如果它们不是立即可用)时。默认设置是0,这意味着驱动程序当找到一个或多个元素的指令时,搜索开始并且结果立即可用。

在这种情况下,在重新加载网页后,一个或多个元素可能会/可能不会在立即搜索中找到。因此,您的Automation Framework 可能会遇到以下任何异常:

NoSuchElementException TimeoutException ElementNotVisibleException ElementNotSelectableException

因此你需要诱导ImplicitWait。通过引入ImplicitWait,驱动程序 将轮询DOM Tree 以配置查找元素或元素的时间量。到那时,您一直在寻找的一个或多个元素可能在 DOM 中可用。在您的代码中,您已经将 ImplicitWait 设置为 10 秒的值,驱动程序 将轮询 DOM 10 秒。

Python:

driver.implicitly_wait(10)

Java:

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

最后,一旦您设置了 ImplicitWaitWebDriver 实例,即 驱动程序 就能够在其生命周期内执行此配置。但是,如果您需要将 WebDriver 实例(即 driver 的粗略时间更改为 wait,那么您可以重新配置它,如下所示:

Python:

driver.implicitly_wait(5)

Java:

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

如果您想在任何时候使 ImplicitWait 无效,您可以按如下方式重新配置它:

Python:

driver.implicitly_wait(0)

Java:

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

流畅的等待

Fluent Wait 是Wait 接口的实现,通过它我们可以动态配置超时轮询间隔FluentWait 的实例可以定义为配置等待条件的最长时间以及必须检查条件的频率。用户还可以配置等待以在等待元素时忽略特定类型的异常,例如页面上的NoSuchElementException

用法:

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

显式等待

ExplicitWait 俗称WebDriverWait 是FluentWait 的专门实现,用户可以通过它来定义、配置和实现WebDriver 实例等待某个条件满足之前继续下一行代码。有一些方法可以帮助我们实现ExplicitWait,它们只会在需要的时候等待。 WebDriverWait 与 ExpectedConditions 结合是实现 ExplicitWait 的方式之一。

一个例子:

import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
.
.
.
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("element_xpath")));
element.click();

解释:

ExplicitWait 的这个实现在抛出 TimeoutException 之前最多等待 10 秒,或者如果它找到该元素,那么它将在 0 到 10 秒内返回。 WebDriverWait 默认每 500 毫秒调用一次 ExpectedCondition,直到它成功返回。 ExpectedCondition 函数类型的成功返回值是 Boolean 值为 true 或非空对象。


预期条件:

在为测试 Web/移动应用程序而自动化 Web 浏览器时,经常会遇到一些情况。 Java、C# 和 Python 绑定包含这些方便的方法,因此我们不必自己编写 ExpectedCondition 类或为它们创建自己的实用程序包。一些预期条件是:

alertIsPresent() elementToBeClickable(locator) elementToBeSelected(WebElement) frameToBeAvailableAndSwitchToIt(locator) invisibilityOf(element)

你可以在这里找到Expected Conditions支持的所有方法。


这个特定的查询:

搜索单个元素时,驱动程序将轮询 OM,直到找到该元素或配置的超时到期,然后再抛出 NoSuchElementException。 在搜索多个元素时,驱动程序将轮询 DOM,直到找到至少一个元素或配置的超时已过期。

因此,根据第一种情况,驱动程序将仅等待 3 秒

【讨论】:

【参考方案3】:

如果我们在隐式等待中设置 10 秒并且在 10 秒之前,则在 3 秒内只有元素被定位。

到时候它会继续进行,而不是等待设定的时间..

【讨论】:

以上是关于隐式 vs 显式 vs Fluent 等待的主要内容,如果未能解决你的问题,请参考以下文章

fluent中的UDF能用vs2010编译吗?

隐式等待和显式等待之间的内部工作区别是啥

java+selenium3隐式等待+显式等待

webdriver显式和隐式等待

selenium强制等待,隐式等待,显式等待

显式等待和隐式等待