澄清混合原因Selenium doc的隐式和显式等待

我正在阅读SeleniumHQ文档,并且遇到以下声明。

警告:不要混合隐式和显式的等待,这样做会导致不可预知的等待时间,例如设置10秒的隐式等待和15秒的显式等待,可能导致20秒后发生超时。

出于某种原因,我无法理解这一点。 总超时20秒是我的主要困惑点。 任何人都可以解释,如果我错过了什么?

编辑

我的问题不是混合这些等待的实施/后果。 这完全是关于文档的超时声明和计算。

第二编辑

看起来像下面的testing文档是正确的。 我仍然需要解释

只是隐含的等待

using System; using System.Diagnostics; using NUnit.Framework; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; namespace Test { [TestFixture] public class Test { private IWebDriver _webDriver; [Test] public void ExplicitVsImplicitWaitTest() { _webDriver = new ChromeDriver(); _webDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10)); _webDriver.Navigate().GoToUrl("https://www.google.com/"); _webDriver.Manage().Window.Maximize(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); try { //new WebDriverWait(_webDriver, TimeSpan.FromSeconds(15)).Until( //ExpectedConditions.ElementExists(By.CssSelector("Should Fail"))); _webDriver.FindElement(By.CssSelector("Should Fail")); } catch ( NoSuchElementException exception) //catch ( OpenQA.Selenium.WebDriverTimeoutException) { stopwatch.Stop(); Console.WriteLine(stopwatch.Elapsed); } _webDriver.Quit(); } } } 

时间秒:00:00:10.0167290

只是明确的等待

 using System; using System.Diagnostics; using NUnit.Framework; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; namespace Test { [TestFixture] public class Test { private IWebDriver _webDriver; [Test] public void ExplicitVsImplicitWaitTest() { _webDriver = new ChromeDriver(); //_webDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10)); _webDriver.Navigate().GoToUrl("https://www.google.com/"); _webDriver.Manage().Window.Maximize(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); try { new WebDriverWait(_webDriver, TimeSpan.FromSeconds(15)).Until( ExpectedConditions.ElementExists(By.CssSelector("Should Fail"))); _webDriver.FindElement(By.CssSelector("Should Fail")); } //catch ( NoSuchElementException exception) catch ( OpenQA.Selenium.WebDriverTimeoutException) { stopwatch.Stop(); Console.WriteLine(stopwatch.Elapsed); } _webDriver.Quit(); } } } 

时间秒:00:00:15.2463079

混合,显式和隐式两种

 using System; using System.Diagnostics; using NUnit.Framework; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; namespace Test { [TestFixture] public class Test { private IWebDriver _webDriver; [Test] public void ExplicitVsImplicitWaitTest() { _webDriver = new ChromeDriver(); _webDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10)); _webDriver.Navigate().GoToUrl("https://www.google.com/"); _webDriver.Manage().Window.Maximize(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); try { new WebDriverWait(_webDriver, TimeSpan.FromSeconds(15)).Until( ExpectedConditions.ElementExists(By.CssSelector("Should Fail"))); _webDriver.FindElement(By.CssSelector("Should Fail")); } //catch ( NoSuchElementException exception) catch ( OpenQA.Selenium.WebDriverTimeoutException) { stopwatch.Stop(); Console.WriteLine(stopwatch.Elapsed); } _webDriver.Quit(); } } } 

时间秒:00:00:20.5771817

我的问题不在于执行那些等待。 这完全是关于文档的超时声明和计算。

但是你必须知道它们是如何实现的,以了解发生了什么。 这是两种types的等待混合情况。 我正在嘲笑那些对讨论不重要的步骤。

  1. 你的脚本设置了一个隐含的等待。

  2. 你的脚本启动一个明确的等待检查元素是否存在。 轮询显式等待工作 。 所以它发送一个命令给浏览器来检查元素的存在。

  3. 由于已经设置了隐含的等待,发送给浏览器的命令需要10秒才能返回失败。

  4. 你明确的等待检查是否已经达到15s的时间限制。 目前处于等待状态的时间为10秒(+执行脚本所需的时间很less,networking延迟等),小于15秒。 所以没有完成等待并重新发出上面第2步中的命令。

  5. 由于隐含的等待,发送给浏览器的命令需要10秒才能返回失败。

  6. 当明确的等待再次检查自己的超时时间时,已超过15秒,因此超时。

因此,明确的等待轮询两次,每次需要10秒,这意味着总计20秒(加上记帐的时间很less)。

明确的等待不会做任何事情来检测和补偿已经设置的隐式等待。 而且它不会与发送给浏览器的命令并行地继续运行。 在执行浏览器命令时,显式等待不会进行任何记帐或超时。 在检查是否应该超时之前,必须等待浏览器命令完成。