何时在Selenium Webdriver中使用显式等待与隐式等待?

2022-08-31 16:50:35

我正在使用:

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

但对于以下元素,它仍然连续失败

    driver.findElement(By.id("name")).clear();
    driver.findElement(By.id("name")).sendKeys("Create_title_01");

我添加了等待代码:

for (int second = 0;; second++) {
        if (second >= 120) fail("timeout");
        try { if (isElementPresent(By.id("name"))) break; } catch (Exception e) {}
        Thread.sleep(1000);
    }

隐式等待难道不应该照顾好等到找到一个元素吗?另外,如果我使用显式等待而不是我添加的代码会更好吗?Thread.sleep()


答案 1

TL;DR:始终使用显式等待。忘记隐式等待的存在。


以下是显式等待和隐式等待之间差异的快速概述:

显式等待:

  • 记录和定义的行为。
  • 在硒的本地部分运行(以代码的语言)。
  • 适用于您能想到的任何条件。
  • 返回成功或超时错误。
  • 可以将元素的缺失定义为成功条件。
  • 可以自定义重试和异常之间的延迟以忽略。

隐式等待:

  • 未记录且实际上未定义的行为。
  • 在硒的远程部分(控制浏览器的部分)运行。
  • 仅适用于查找元素方法。
  • 返回找到的元素或(超时后)未找到的元素。
  • 如果检查元素是否不存在,则必须始终等到超时。
  • 除了全局超时之外,无法自定义。

带说明的代码示例。第一个隐式等待:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));

现在显式等待:

WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement myDynamicElement = wait.until(
  ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));

这两个代码示例都执行相同的操作。找到某个元素,如果在10秒后没有找到,就放弃。隐式等待只能执行此操作。它只能尝试查找具有超时的元素。显式等待的优势在于它可以等待各种条件。还可以自定义超时并忽略某些异常。

可能条件的示例:或 。以下是内置预期条件的列表:https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.htmlelementToBeClickablenumberOfElementsToBeMoreThaninvisibilityOf

更多解释:

隐式等待超时仅对方法有效。如果设置,那么所有人都将“等待”设置的时间,然后再声明找不到该元素。findElement*findElement*

遗嘱等待方式未定义。这取决于浏览器或操作系统或硒的版本。可能的实现包括:findElement*

  • 反复尝试查找元素,直到超时。找到元素后立即返回。
  • 尝试查找元素。等到超时。再试一次。
  • 等到超时。尝试查找元素。

此列表是从观察和阅读错误报告以及粗略阅读硒源代码中收集的。


我的结论是:隐含的等待是不好的。功能有限。该行为是未记录的,并且取决于实现。

显式等待可以完成所有隐式等待可以完成的工作,甚至更多。显式等待的唯一缺点是代码更加冗长。但是这种冗长使代码变得明确。显式比隐式更好。右?


延伸阅读:


答案 2

隐式等待 - 它是适用于所有元素的全局设置,如果元素在指定时间之前出现,则脚本将开始执行,否则脚本将抛出 。在设置方法中使用的最佳方式。仅影响 .NoSuchElementExceptionBy.findelement()

Thread.sleep()- 它将为脚本的睡眠时间,不是在脚本中使用的好方法,因为它是无条件的睡眠。如果在5%的情况下,2秒是不够的怎么办?

显式等待:等待指定包含/属性更改。当应用程序向系统提供AJAX调用并获取动态数据并在UI上呈现时,更常用。在这种情况下是合适的。WebDriverWait


推荐