澄清 Selenium doc 中混合隐式和显式等待的原因 [英] Clarification of the cause of mixing Implicit and Explicit waits in Selenium doc

查看:18
本文介绍了澄清 Selenium doc 中混合隐式和显式等待的原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 SeleniumHQ 文档并来了跨越以下陈述.

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

出于某种原因,我无法理解这一点.总超时 20 秒是我的主要困惑点.如果我遗漏了什么,谁能解释一下?

编辑

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

第二次编辑

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

只是隐式等待

使用系统;使用 System.Diagnostics;使用 NUnit.Framework;使用 OpenQA.Selenium;使用 OpenQA.Selenium.Chrome;命名空间测试{[测试夹具]公开课测试{私人 IWebDriver _webDriver;[测试]公共无效 ExplicitVsImplicitWaitTest(){_webDriver = new ChromeDriver();_webDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));_webDriver.Navigate().GoToUrl("https://www.google.com/");_webDriver.Manage().Window.Maximize();秒表秒表 = new Stopwatch();秒表.Start();尝试{//new WebDriverWait(_webDriver, TimeSpan.FromSeconds(15)).Until(//ExpectedConditions.ElementExists(By.CssSelector("应该失败")));_webDriver.FindElement(By.CssSelector("应该失败"));}捕获(NoSuchElementException 异常)//catch (OpenQA.Selenium.WebDriverTimeoutException){秒表.Stop();Console.WriteLine(秒表.Elapsed);}_webDriver.Quit();}}}

<块引用>

以秒为单位的时间:00:00:10.0167290

只是显式等待

使用系统;使用 System.Diagnostics;使用 NUnit.Framework;使用 OpenQA.Selenium;使用 OpenQA.Selenium.Chrome;使用 OpenQA.Selenium.Support.UI;命名空间测试{[测试夹具]公开课测试{私人 IWebDriver _webDriver;[测试]公共无效 ExplicitVsImplicitWaitTest(){_webDriver = new ChromeDriver();//_webDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));_webDriver.Navigate().GoToUrl("https://www.google.com/");_webDriver.Manage().Window.Maximize();秒表秒表 = new Stopwatch();秒表.Start();尝试{新的 WebDriverWait(_webDriver, TimeSpan.FromSeconds(15)).Until(ExpectedConditions.ElementExists(By.CssSelector("应该失败")));_webDriver.FindElement(By.CssSelector("应该失败"));}//catch (NoSuchElementException 异常)捕捉(OpenQA.Selenium.WebDriverTimeoutException){秒表.Stop();Console.WriteLine(秒表.Elapsed);}_webDriver.Quit();}}}

<块引用>

以秒为单位的时间:00:00:15.2463079

混合、显式和隐式两者

使用系统;使用 System.Diagnostics;使用 NUnit.Framework;使用 OpenQA.Selenium;使用 OpenQA.Selenium.Chrome;使用 OpenQA.Selenium.Support.UI;命名空间测试{[测试夹具]公开课测试{私人 IWebDriver _webDriver;[测试]公共无效 ExplicitVsImplicitWaitTest(){_webDriver = new ChromeDriver();_webDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));_webDriver.Navigate().GoToUrl("https://www.google.com/");_webDriver.Manage().Window.Maximize();秒表秒表 = new Stopwatch();秒表.Start();尝试{新的 WebDriverWait(_webDriver, TimeSpan.FromSeconds(15)).Until(ExpectedConditions.ElementExists(By.CssSelector("应该失败")));_webDriver.FindElement(By.CssSelector("应该失败"));}//catch (NoSuchElementException 异常)捕捉(OpenQA.Selenium.WebDriverTimeoutException){秒表.Stop();Console.WriteLine(秒表.Elapsed);}_webDriver.Quit();}}}

<块引用>

以秒为单位的时间:00:00:20.5771817

解决方案

我的问题不是关于这些等待的实施.完全是关于文档上的语句和超时计算.

但是您必须知道它们是如何实现的才能理解正在发生的事情.这是您混合使用两种等待时会发生的情况.我跳过了那些对讨论不重要的步骤.

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

  2. 您的脚本开始显式等待,检查元素是否存在.显式等待通过轮询工作.所以它向浏览器发送一个命令来检查元素是否存在.

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

  4. 您的显式等待检查它是否已达到其时间限制,即 15 秒.目前等待的时间为 10 秒(+ 执行脚本、网络延迟等所需的少量时间),不到 15 秒.所以它没有完成等待并重新发出与上面第 2 步相同的命令.

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

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

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

显式等待不会检测和补偿已设置的隐式等待.它不会继续与它发送给浏览器的命令并行运行.在执行浏览器命令时,显式等待不会进行任何记账或超时.在检查它是否应该超时之前,它必须等待浏览器命令完成.

I was reading the SeleniumHQ documentation and came across the following statements.

"WARNING: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example setting an implicit wait of 10s and an explicit wait of 15 seconds, could cause a timeout to occur after 20 seconds."

For some reason, I cannot get this to make sense. The total timeout 20s is the main confusion point for me. Can anyone explain if I am missing something?

EDIT

My question is not about the implementation/consequences of mixing those waits. It's entirely about the statements and calculation of timeout on the doc.

2nd Edit

Looks like the doc is correct according to the tests below. I still need the explanation though.

Just Implicit wait

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();

        }
    }
}

Time in second: 00:00:10.0167290

Just Explicit wait

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();

        }
    }
}

Time in second: 00:00:15.2463079

Mixed, Explicit and Implicit both

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();

        }
    }
}

Time in second: 00:00:20.5771817

解决方案

My question is not about the implementation of those waits. It's entirely about the statements and calculation of timeout on the doc.

But you have to know how they are implemented to make sense of what is going on. Here is what happens with your mix of the two types of waits. I'm kipping over those steps that are not important for the discussion.

  1. Your script sets an implicit wait.

  2. Your script starts an explicit wait checking whether the element exists. The explicit wait works by polling. So it sends a command to the browser to check for the existence of the element.

  3. Because of the implicit wait already set, the command sent to the browser takes 10 seconds to return a failure.

  4. Your explicit wait checks whether it has reached its time limit which is 15s. It is currently at 10s (+ a tiny amount of time taken to execute the script, network latency, etc.) into the wait, which is less then 15s. So it is not done waiting and reissues the same command as in step 2 above.

  5. Because of the implicit wait, the command sent to the browser takes 10 seconds to return a failure.

  6. When the explicit wait checks again for its own timeout, more than 15s have elapsed, so it times out.

So the explicit wait polls twice, and each time takes 10 seconds which mean 20 seconds total (plus a tiny amount of time to account for the bookkeeping).

An explicit wait does not do anything to detect and compensate for an implicit wait that has been set. And it does not continue running in parallel to the commands it sends to the browser. While a browser command executes, the explicit wait is not doing any bookkeeping or able to time out. It has to wait for the browser command to complete before checking whether it should time out.

这篇关于澄清 Selenium doc 中混合隐式和显式等待的原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆