Selenium 简明 — 理解 Selenium 中的等待(隐式等待 vs 显式等待)
抱歉,我无法直接访问外部链接获取文章内容。请您把需要翻译的文本粘贴到这里,我会按照要求保留源链接并将内容翻译成简体中文。
介绍
在上一篇文章中,我们学习了 Selenium 如何使用定位器在网页上查找元素。
初学者经常会遇到 NoSuchElementException 或 ElementNotInteractableException 等错误,即使页面上确实存在该元素。
其原因通常是 时机。现代 Web 应用会动态加载元素,因此 Selenium 可能在元素出现之前就尝试与之交互。Selenium 执行脚本的速度远快于真实用户的操作:
- 打开页面
- 查找元素
- 点击按钮
如果页面仍在后台加载内容,Selenium 可能会尝试定位尚未出现的元素,从而导致测试失败。
等待 让 Selenium 暂停执行,直到满足某个条件(例如元素可见、可点击,或页面加载完成)。一旦条件满足,Selenium 继续执行脚本。
Selenium 提供了两种主要的等待方式:
- 隐式等待
- 显式等待
隐式等待
隐式等待告诉 Selenium 在搜索元素时等待指定的时间。如果元素没有立即被找到,Selenium 会持续尝试,直到超时为止。
// 设置隐式等待为 10 秒
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
这意味着什么
- Selenium 在定位元素时最多等待 10 秒。
- 如果元素提前出现,Selenium 会立即继续执行。
driver.findElement(By.id("loginButton")).click(); // 如有需要,最多等待 10 秒
如果元素需要 3 秒才加载完成,Selenium 会等待这 3 秒,然后点击它。
显式等待
显式等待更灵活。它允许 Selenium 等待特定条件,例如可见性、可点击性或文本的存在。
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("loginButton"))
);
这里 Selenium 会等待元素在页面上变得可见。
常见的预期条件
visibilityOfElementLocatedelementToBeClickablepresenceOfElementLocatedtitleContains
示例
wait.until(ExpectedConditions.elementToBeClickable(By.id("submit")));
这确保在与元素交互之前,该元素是可点击的。
比较:隐式等待 vs. 显式等待
| 特性 | 隐式等待 | 显式等待 |
|---|---|---|
| 范围 | 全局适用 | 针对特定元素 |
| 灵活性 | 有限 | 非常灵活 |
| 使用方式 | 简单 | 更可控 |
| 是否推荐用于复杂场景 | 否 | 是 |
在大多数现代自动化框架中,显式等待更受青睐,因为它们能够更好地控制测试行为。
为什么不使用 Thread.sleep()?
一些初学者使用 Thread.sleep() 来暂停测试:
Thread.sleep(5000); // pause for exactly 5 seconds
这种做法的问题
- 使测试变慢
- 不可靠(如果元素加载较晚会失败)
- 难以维护
使用 Selenium 内置的等待机制是更好的解决方案。
典型的 Selenium 测试流程(带等待)
Open Page
↓
Find Element
↓
Wait Until Element Is Ready
↓
Perform Action
加入等待可以使自动化脚本更稳定、更可靠。时序问题是导致 Selenium 测试失败的最常见原因之一。正确使用等待可确保 Selenium 仅在元素准备就绪时与之交互,从而使测试具备以下特点:
- 更可靠
- 更少不稳定
- 更易维护
系列回顾 & 接下来
到目前为止,本系列已涵盖:
- Selenium 架构
- 定位器
- 等待
下一篇文章: Selenium 简明 — 处理警报、框架和多窗口
这些功能在现代 Web 应用中很常见,需要 Selenium 在不同上下文之间切换控制。