Selenium:显式/无条件等待,即 "just wait"

Selenium: Explicit / Unconditional wait, i.e. "just wait"

事实证明,WebDriverWait class 不允许 "unconditional wait":您总是必须指定要等待的特定条件。但是,例如在设置项目和开发第一个测试时,无条件等待是一个有用的功能。通常不鼓励使用 Thread.sleep()。 "just wait" 问题有更好的解决方案吗?

我目前使用的是最新的 Selenium/WebDriver 版本 - 2.44.0

如果只是等待,那么Sleep就可以了。

不使用 Sleep 的关键不在于睡眠本身,而在于 只是等待 ,正如您所描述的那样。 只是等待是你不应该的。尝试改变你的想法,找到一些你可以附加等待的事件。使其成为有条件的。

在网络测试中,您通常不需要等待。你等到页面加载,直到动画完成,直到表单发送,元素可点击,用户登录,脚本执行,数据被处理......这就是为什么 Sleep 不鼓励,但如果你真的 不要 有一个你正在等待的事件,只需要 等待 ,然后使用 Sleep 就完全可以了。

就原理而言是正确的,换句话说:

Do not "just wait" if you can actually wait for something significant to happen in the browser. In other words, you be waiting for a specific event rather than "just waiting".

好的,但是为了便于讨论,让我们假设您所处的情况绝对肯定没有您可以等待的事件。我有使用 Selenium 的大型测试套件,我从未遇到过这种情况,但我并非无所不知。可能会有我没有预见到的情况。 Thread.sleep() 可能会给你想要的,但是:

  1. 如果您 运行 您的浏览器在 Sauce Labs 或 Browser Stack 等远程配置服务上,他们可能会认为您的脚本已死并关闭浏览器。 (Sauce Labs 绝对是这样做的。我从未使用过 Browser Stack,但我也希望如此。)

  2. 如果在您等待的过程中发生网络问题并导致测试失败,您在 Thread.sleep() 调用完成后才会知道。如果您使用我上面提到的那些服务,同样会发生这种情况。它偶尔会发生在我的测试套件中。

  3. 或者在本地测试的话:浏览器崩溃或者进入死循环。我没有经历过崩溃,但我经历过无限循环。同样,如果您使用 Thread.sleep(),您在等待完成之前不会知道该问题。

当然,你想等的时间越长,问题就越大。如果你只是想等一秒钟......那么你应该没问题 Thread.sleep()。否则,如果我被逼到墙角并且不得不到"just wait"我会仍然使用Selenium的等待设施,我会做类似于:

try: 
    WebDriverWait(driver, timeout).until(
        lambda driver: driver.execute_script("return false"))
except TimeoutException:
    pass # Do nothing

这是 Python 代码,但原理在 Selenium 支持的任何语言中都是相同的:等待永远不会发生的事情。 重要的是等待执行在浏览器端发生的测试,因为这样做而不是使用 Thread.sleep() 之类的东西的全部意义在于联系浏览器并且我们尽早发现问题 WebDriverWait 的工作方式,它会每隔一段时间轮询一次浏览器(在 Python 实现中默认为每 0.5 秒一次)。测试可以是 find_element 搜索不存在的元素的方法。我使用了一个 execute_script 和 return 的 false。由于它永远不会达到 return 一个 true 值,等待将超时。 (执行一个空脚本也可以,因为它会 return undefined 转换为虚假值,但 return false 看起来是故意的,而空脚本看起来像是一个错误。)然后你只需要忽略由于超时引发的异常。如果你经常这样做,你甚至可以将整个事情包装在一个效用函数中。