# 9 小时 WebDriver – 隐式等待

> 原文： [https://javabeginnerstutorial.com/selenium/9h-webdriver-implicit-waits/](https://javabeginnerstutorial.com/selenium/9h-webdriver-implicit-waits/)

它说：“时间具有向我们展示真正重要内容的绝妙方式”。 但是，等到一切变为现实，这一点同样重要。 如今，网页大多使用 javascript 和 ajax 技术开发。 结果，页面上的不同元素在不同的时间加载。 当我们使用 selenium WebDriver 自动化我们的手动测试并将其作为测试套件运行时，是时候提防您了，因为您可能会遇到 Selenium 的怪异行为。

您的测试用例可以成功运行，并且一次执行一行时可以按预期工作，但是作为套件/批处理运行时，它可能会失败。 挠头以了解其背后的原因？ 让我们潜入更多！

当我们使用`driver.get（"url_we_wish_to_access")`，`driver.navigate().to("url")`或单击超链接等时，这些调用将启动页面 在该加载活动完成之前加载并返回。 因此，如果页面的加载线程尚未填充 Web 元素，而您尝试使用`driver.findElement("locating_strategy")`找到它，则得到的只是**异常**即`NoSuchElementException`，`ElementNotVisibleException`等。

所有这些意味着我们必须找到一种告诉 Selenium 的方法，我们希望它等待一定的时间，或者直到 Web 元素变得可访问/可单击/显示为止，然后再引发可怕的异常。 在那里，不要惊慌。 我看到一些汗珠滴到你的额头上！ 那么，如何使这种压力成为我们自己的大力水手菠菜的版本呢？ 感谢**隐式，显式和流畅的等待**。

是时候去拜访每一个了。

### 隐式等待

了解我们使用`findElement`或`findElements`命令在 WebDriver 中定位 Web 元素非常重要（后面的文章将详细介绍该主题以及各种定位策略）。 因此，当尝试在页面上查找特定的 Web 元素时，如果该 Web 元素不是立即可用的，则隐式等待告诉 WebDriver 在指定的时间内轮询 DOM。 万一在指定的等待时间内找到该元素，测试将继续执行。 如果不是，则抛出`NoSuchElementException`。

下面是带有隐式等待命令的代码片段，以使您更好地理解，

```java
@Before
	public void setUp() throws Exception{
		// Selenium version 3 beta releases require system property set up
		System.setProperty("webdriver.gecko.driver", "E:\\Selenium\\geckodriver-v0.10.0-win64\\geckodriver.exe");
		// Create a new instance for the class FirefoxDriver
		// that implements WebDriver interface
		driver = new FirefoxDriver();
		// Implicit wait for 3 seconds
		driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
		// Assign the URL to be invoked to a String variable
		baseUrl = "https://www.google.com";
		pageTitle = "";
		expectedTitle = "Google";
	} 
```

如突出显示的那样，使用隐式等待的语法是：

```java
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
```

隐式等待有两个参数。 在此示例中，我们的第一个参数为 **3** ，这是它必须等待的时间，第二个参数为`TimeUnit.SECONDS`。 这是时间测量。 可以指定为`DAYS`，`HOURS`，`MINUTES`，`SECONDS`，`MILLISECONDS`，`MICROSECONDS`，`NANOSECONDS`等。

此外，在键入此语句时，“`TimeUnit`”下方会出现一条弯曲的线。 悬停时，蚀将建议所有可能的快速修复。 单击建议导入`java.util.concurrent.TimeUnit`包的第一个修复程序。

1.  隐式等待只需要初始化一次。 设置后，它将适用于`WebDriver`对象实例的寿命。 换句话说，它将在浏览器打开的整个过程中就位。 因此，WebDriver 将等待该额外时间，然后对所有[`findElement`](https://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebDriver.html#findElement(org.openqa.selenium.By))和[`findElements`](https://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebDriver.html#findElements(org.openqa.selenium.By))抛出异常
2.  默认时间设置为 0。
3.  隐式等待仅影响`finddElement(s)`，它不影响其他`WebDriver`方法，例如`driver.getCurrentUrl()`等。
4.  在大多数情况下，尤其是在调试时，仅“`NoSuchElementException`”并不是很有用。 我们可能希望使用更多信息来自定义此错误消息，例如捕获屏幕快照或添加更多详细信息等。可以通过在每次`finddElement(s)`调用周围使用`try-catch`块来实现此目的，但这不是我们使用隐式等待的目标 因为这是一个全球性的时间设置。
5.  由于有大量的 JavaScript，因此可能会出现一些奇怪的情况。 即使该元素位于 DOM 中，也可能无法立即单击或显示或启用它。 结果我们可能会看到[`ElementNotVisibleException`](https://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/ElementNotVisibleException.html)，[`WebDriverException`](https://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebDriverException.html)，[`StaleElementReferenceException`](https://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/StaleElementReferenceException.html)
6.  由于不同的元素可能在不同的时间加载，因此我们可能会说服将等待时间设置为较高的值（或等效于最慢的 Web 元素的加载时间），例如 20 秒左右。 我们对此的理由是，“无论如何，所有元素的加载速度都将比此时快，并且测试将按预期进行。” 但是您甚至猜不到**性能** - 这种方法不是一个好主意吗？ 我在这里给您举几个例子，以便更好地了解，

**情况 1**：如果希望找到一个元素，但无论结果如何，都可以继续进行测试。

**情况 2**：如果仅需要验证是否缺少某个元素，例如等待警报框出现并关闭它。 即使这样，WebDriver 也将不得不等到超时，即在这种情况下为 20 秒。 在庞大的测试套件中运行时，这将产生巨大的影响。

为了克服隐式等待的一些缺点，我们有明确的等待来救援！ 但是考虑到我们的大脑一次只能占用那么多的空间，我将在下一篇文章中保留这个主题。

再见！ 有一个值得期待的一天！

