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()
可能会给你想要的,但是:
如果您 运行 您的浏览器在 Sauce Labs 或 Browser Stack 等远程配置服务上,他们可能会认为您的脚本已死并关闭浏览器。 (Sauce Labs 绝对是这样做的。我从未使用过 Browser Stack,但我也希望如此。)
如果在您等待的过程中发生网络问题并导致测试失败,您在 Thread.sleep()
调用完成后才会知道。如果您使用我上面提到的那些服务,同样会发生这种情况。它偶尔会发生在我的测试套件中。
或者在本地测试的话:浏览器崩溃或者进入死循环。我没有经历过崩溃,但我经历过无限循环。同样,如果您使用 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
看起来是故意的,而空脚本看起来像是一个错误。)然后你只需要忽略由于超时引发的异常。如果你经常这样做,你甚至可以将整个事情包装在一个效用函数中。
事实证明,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()
可能会给你想要的,但是:
如果您 运行 您的浏览器在 Sauce Labs 或 Browser Stack 等远程配置服务上,他们可能会认为您的脚本已死并关闭浏览器。 (Sauce Labs 绝对是这样做的。我从未使用过 Browser Stack,但我也希望如此。)
如果在您等待的过程中发生网络问题并导致测试失败,您在
Thread.sleep()
调用完成后才会知道。如果您使用我上面提到的那些服务,同样会发生这种情况。它偶尔会发生在我的测试套件中。或者在本地测试的话:浏览器崩溃或者进入死循环。我没有经历过崩溃,但我经历过无限循环。同样,如果您使用
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
看起来是故意的,而空脚本看起来像是一个错误。)然后你只需要忽略由于超时引发的异常。如果你经常这样做,你甚至可以将整个事情包装在一个效用函数中。