澄清 Selenium 文档中混合隐式和显式等待的原因
Clarification of the cause of mixing Implicit and Explicit waits in Selenium doc
我在阅读 SeleniumHQ 文档时发现了以下语句。
"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."
出于某种原因,我无法理解这一点。总超时 20 秒是我的主要困惑点。谁能解释一下我是否遗漏了什么?
编辑
我的问题不是关于混合这些等待的 implementation/consequences。完全是文档上关于timeout的语句和计算。
第二次编辑
根据下面的测试,文档看起来是正确的。 虽然我还需要解释。
只是隐式等待
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
只是显式等待
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
混合的,显式的和隐式的
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.
但是您必须知道它们是如何实现的才能理解正在发生的事情。以下是混合使用两种类型的等待会发生什么。我跳过了那些对讨论不重要的步骤。
您的脚本设置了隐式等待。
您的脚本开始显式等待以检查元素是否存在。显式等待 通过轮询 工作。因此它向浏览器发送命令以检查该元素是否存在。
由于已经设置了隐式等待,发送到浏览器的命令需要 10 秒才能return失败。
您的显式等待检查它是否已达到 15 秒的时间限制。目前等待时间为 10 秒(+ 执行脚本所花费的少量时间、网络延迟等),不到 15 秒。所以它没有等待并重新发出与上面步骤 2 中相同的命令。
由于隐式等待,发送到浏览器的命令需要 10 秒才能return失败。
显式等待再次检查自身超时时,超过15s,超时。
所以显式等待轮询两次,每次需要 10 秒,这意味着总共 20 秒(加上一小部分时间用于簿记)。
显式等待不会检测和补偿已设置的隐式等待。并且它不会继续 运行 与它发送给浏览器的命令并行。当浏览器命令执行时,显式等待不会进行任何簿记或超时。它必须等待浏览器命令完成才能检查它是否应该超时。
我在阅读 SeleniumHQ 文档时发现了以下语句。
"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."
出于某种原因,我无法理解这一点。总超时 20 秒是我的主要困惑点。谁能解释一下我是否遗漏了什么?
编辑
我的问题不是关于混合这些等待的 implementation/consequences。完全是文档上关于timeout的语句和计算。
第二次编辑
根据下面的测试,文档看起来是正确的。 虽然我还需要解释。
只是隐式等待
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
只是显式等待
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
混合的,显式的和隐式的
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.
但是您必须知道它们是如何实现的才能理解正在发生的事情。以下是混合使用两种类型的等待会发生什么。我跳过了那些对讨论不重要的步骤。
您的脚本设置了隐式等待。
您的脚本开始显式等待以检查元素是否存在。显式等待 通过轮询 工作。因此它向浏览器发送命令以检查该元素是否存在。
由于已经设置了隐式等待,发送到浏览器的命令需要 10 秒才能return失败。
您的显式等待检查它是否已达到 15 秒的时间限制。目前等待时间为 10 秒(+ 执行脚本所花费的少量时间、网络延迟等),不到 15 秒。所以它没有等待并重新发出与上面步骤 2 中相同的命令。
由于隐式等待,发送到浏览器的命令需要 10 秒才能return失败。
显式等待再次检查自身超时时,超过15s,超时。
所以显式等待轮询两次,每次需要 10 秒,这意味着总共 20 秒(加上一小部分时间用于簿记)。
显式等待不会检测和补偿已设置的隐式等待。并且它不会继续 运行 与它发送给浏览器的命令并行。当浏览器命令执行时,显式等待不会进行任何簿记或超时。它必须等待浏览器命令完成才能检查它是否应该超时。