【问题标题】:Fluent wait vs WebDriver waitFluent 等待 vs WebDriver 等待
【发布时间】:2016-11-22 23:09:41
【问题描述】:

我对@9​​87654321@ 和WebDriverWait 感到困惑。

FluentWaitWebDriverwait 都使用相同的功能,例如忽略异常、更改轮询时间间隔、预期条件等。

据我了解,两者都实现了Wait 接口。此外,WebDriverWait 扩展了FluentWait(这意味着所有功能也存在于WebDriverWait 中)。

WebDriverWait 拥有哪些额外功能,FluentWait 中没有?

【问题讨论】:

    标签: java selenium selenium-webdriver


    【解决方案1】:

    FluentWait 和 WebDriverWait 都是 Wait 接口的实现。

    使用 Fluent WebDriver Explicit Wait 和 WebDriver Explicit Wait 的目标大致相同。但是,在少数情况下,FluentWait 可以更加灵活。由于这两个类都是同一个 Wait 接口的实现,所以它们或多或少都具有相同的特性,除了 FluentWait 具有在 until 方法中接受谓词或函数作为参数的特性。另一方面,WebDriverWait 只接受作为 ExpectedCondition in until 方法的函数,这限制了您只能使用布尔返回。当您在 FluentWait 中使用 Predicate 时,它​​允许您从 until 返回任何对象方法。

    这里仔细看:https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/FluentWait.html#until-com.google.common.base.Predicate-

    示例: FluentWait 具有 Function 作为参数,直到 String 返回:

    public void exampleOfFluentWait() {
            WebElement foo = driver.findElement(By.id("foo"));
            new FluentWait<WebElement>(foo)
                .withTimeout(10, TimeUnit.SECONDS)
                .pollingEvery(2, TimeUnit.SECONDS)
                        .until(new Function<WebElement, String>() {
                            @Override
                            public String apply(WebElement element) {
                                return element.getText();
                            }
                        });
        }
    

    具有布尔返回函数的相同 FluentWait 作为直到方法中的参数。

    public void exampleOfFluentWait() {
                WebElement foo = driver.findElement(By.id("foo"));
                new FluentWait<WebElement>(foo)
                    .withTimeout(10, TimeUnit.SECONDS)
                    .pollingEvery(2, TimeUnit.SECONDS)
                            .until(new Function<WebElement, Boolean>() {
                                @Override
                                public Boolean apply(WebElement element) {
                                    return element.getText().contains("foo");
                                }
                            });
            }
    

    一个带有谓词的 FluentWait。

    public void exampleOfFluentWithPredicate() {
        WebElement foo = driver.findElement(By.id("foo"));
        new FluentWait<WebElement>(foo)
            .withTimeout(10, TimeUnit.SECONDS)
            .pollingEvery(100, TimeUnit.MILLISECONDS)
                    .until(new Predicate<WebElement>() {
                        @Override
                        public boolean apply(WebElement element) {
                            return element.getText().endsWith("04");
                        }
                    });
    }
    

    WebDriverWait 示例:

    public void exampleOfWebDriverWait() {
            WebElement foo = driver.findElement(By.id("foo"));
    
            new WebDriverWait(driver, 10)
            .pollingEvery(2, TimeUnit.SECONDS)
            .withTimeout(10, TimeUnit.SECONDS)
            .until(ExpectedConditions.visibilityOf(foo));
        }
    

    【讨论】:

    • 您还可以在 WebDriverWait 中使用和定义轮询时间。
    • @DeepakKakkar 改变了我的答案。
    • @PriyanshuShekhar 我对你的回答有点怀疑,我认为谓词不支持apply() 方法,应该是test() 方法。其次,谓词仅返回 boolean 值,但您提到它将返回任何 object。你能澄清一下吗?
    【解决方案2】:

    实际上两者之间几乎没有区别。根据WebDriverWait源代码它说:

    它将忽略遇到的NotFoundException 实例 (抛出)默认情况下在until 条件下,并立即 传播所有其他人。您可以通过以下方式将更多内容添加到忽略列表中 打电话给ignoring(exceptions to add)

    唯一的区别是默认情况下元素未找到异常在WebDriverWait 中被忽略。其余功能与FluentWait 完全相同,因为WebDriverWait 扩展了它。

    【讨论】:

      【解决方案3】:

      主要区别在于,在 Webdriver 等待中,我们无法为等待场景执行池化,而在 Fluent 等待中,我们可以设置在 Webdriver 等待中无法实现的池化时间。

      Webdriver 等待示例

      WebElement dynamicElement = (new WebDriverWait(driver, 10))
        .until(ExpectedConditions.presenceOfElementLocated(By.id("dynamicElement")));
      

      Fluent 等待示例 下面的代码是等待一个元素出现在页面上 30 秒,每 5 秒检查一次它的存在。

       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) {
            driver.findElement(By.id("foo"));    
          }
          });
      

      【讨论】:

        【解决方案4】:

        在 FluentWait 中,轮询周期是受控的,而在 Expicilit 中等待是 250 毫秒。

        用户还可以使用 IgnoreExceptionTypes 命令灵活地忽略轮询期间可能发生的异常。

        【讨论】:

          猜你喜欢
          • 2018-06-17
          • 1970-01-01
          • 2016-08-16
          • 1970-01-01
          • 2020-04-28
          • 2014-04-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多