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

时间:2015-04-06 15:30:00

标签: selenium selenium-webdriver webdriver

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

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

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

修改

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

第二次修改

根据以下测试,该文档看起来是正确的。 我仍然需要解释

只是隐含等待

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

1 个答案:

答案 0 :(得分:23)

  

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

但你必须知道它们是如何实现的,以便了解正在发生的事情。以下是两种等待类型混合的情况。我正在讨论那些对讨论不重要的步骤。

  1. 您的脚本会设置隐式等待。

  2. 您的脚本启动显式等待检查元素是否存在。显式等待通过轮询工作。因此它向浏览器发送命令以检查元素是否存在。

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

  4. 您的显式等待检查是否已达到15秒的时间限制。它目前在等待时间为10秒(执行脚本所需的时间很短,网络延迟等),这不到15秒。所以它没有等待并重新发出与上面步骤2中相同的命令。

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

  6. 当显式等待再次检查其自身的超时时,已超过15秒,因此超时。

  7. 因此,显式等待轮询两次,每次需要10秒,这意味着总共20秒(加上一小部分时间来记账)。

    显式等待不会检测并补偿已设置的隐式等待。并且它不会继续与它发送到浏览器的命令并行运行。执行浏览器命令时,显式等待不执行任何簿记或能够超时。它必须等待浏览器命令完成,然后再检查它是否应该超时。