# 9I WebDriver – 显式等待

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

大家好！ 这篇文章是先前文章“[**9h WebDriver – 隐式等待**](https://javabeginnerstutorial.com/selenium/9h-webdriver-implicit-waits/)”的延续。

事不宜迟，让我们利用“显式等待”的力量。 显式等待需要更多的编码，但是与隐式等待相比，它具有巨大的优势。 在这里，我们可以等到某种情况发生后再进行测试。 如果在指定的超时值内未满足条件，则将引发异常。

语法如下，

```java
WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("element_id")));
```

因此，`WebDriverWait`类用于指定最大超时值，在这种情况下为 15 秒。 `ExpectedCondition`类的方法涵盖了我们希望在测试中出现之前要等待的大多数条件。 这些条件与`WebDriverWait`一起使用。

上面的代码一直等到元素变为可点击（即显示并启用）并返回结果。 默认情况下，`WebDriverWait`每 500 毫秒调用`ExpectedCondition`，直到成功返回。 在这种情况下，它会在抛出`TimeoutException`之前尝试长达 15 秒。 成功的返回值是布尔值`true`或非`null`对象。

`ExpectedCondition`预定义方法的一些示例是，

*   `elementToBeClickable(By locator)` – 用于检查元素的期望是可见的并已启用，以便您可以单击它。
*   `elementToBeSelected(WebElement element)` - 检查是否选择了给定元素。
*   `presenceOfElementLocated(Bylocator)` – 检查页面的 DOM 上是否存在元素。
*   `urlToBe(java.lang.String url)` – 检查当前页面的 URL 是一个特定的 URL。
*   `visibilityOf(WebElement element)` - 用于检查存在于页面的 DOM 上的已知元素的是可见的。

您可以在[此处](https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html)，找到适用于 Java 的`ExpectedConditions`包的所有可用方法及其用法的详细信息。

**注意**：根据 [Selenium 的官方文档](http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp#explicit-and-implicit-waits)，我们警告您不要混合使用隐式和显式等待，因为这可能会导致不可预测的等待时间。

### 流利的等待

谁不喜欢自定义？ 对于显式等待，如果这是您要搜索的内容，那么我建议您使用流利的等待。 我们可以通过流畅的等待来配置以下内容，

*   在抛出异常之前我们希望等待（超时）条件发生的最长时间，
*   检查指定条件的频率，以及
*   我们在等待条件发生时要忽略的异常类型

示例代码段如下所示，

```java
public WebElement fluentWait(final By locator) {
	    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
	            .withTimeout(20, TimeUnit.SECONDS)
	            .pollingEvery(2, TimeUnit.SECONDS)
	            .ignoring(NoSuchElementException.class)
	            .until(new Function<WebDriver, WebElement>() {
	            	public WebElement apply(WebDriver driver) {
	            	return driver.findElement(locator);
	            	}
	            });
	} 
```

在这里，我们声明超时值为 20 秒的流畅等待，每 2 秒（频率）轮询 DOM 直到找到元素为止，并在此时间间隔内忽略`NoSuchElementException`。 我们在上面的代码片段中创建了一个新函数，以在`.until()`中标识此 Web 元素。

#### 有几点值得您花时间

1.  与隐式等待不同，此方法适用于`findElement(s)`以及您可能会想到的在自动化网页时进行枚举的任何其他条件。
2.  可以自定义默认超时值和频率，并且仅将其应用于特定元素，这与隐式等待不同，隐式等待在启动后就适用于`WebDriver`对象实例的寿命。
3.  我们可以实现自己的条件，也可以使用`ExpectedConditions`类中的预定义条件之一。
4.  使用`FluentWait`，我们可以忽略某些异常并改为指定自定义错误消息。 这将我们的调试经验提升到一个全新的水平。
5.  通过忽略特定的异常直到满足我们的条件，流利的等待比隐式等待更可靠。

同意的显式等待包括对代码的更多修饰，但是您认为值得这样做吗？

**注意**： *您可能会想，为什么要经历所有这些痛苦？ 我不能只使用`Thread.sleep()`吗？ 嗯，不，不建议这样做，因为它会使整个测试脚本无条件进入休眠状态。 在大多数情况下，指定的睡眠时间不够长（导致异常），或者变得太长，导致即使元素加载速度更快，测试也要等待。*

**令我全神贯注**：虽然显式等待涉及更多的编程部分，但由于它能够解决很多问题，使我们的生活变得更加轻松，我宁愿选择此方法，而不是隐式等待（基于测试自动化的需求和复杂性涉及*眨眼*）。

您的视线是否模糊？ 不要惊慌，因为所有水域都会落在后面的职位上。 我们将在屏幕截图中看到更实际的等待示例。 一旦涵盖了定位器的类型和策略，就可以更好地理解和掌握该主题。 因此，请继续关注此空间！

在另一个帖子中再见！ 祝你今天愉快！

