所以我尝试使用 C# 和 NUnit 建立一个 Selenium 测试套件。一切似乎都工作正常,直到我的测试持续时间开始超过 6 分钟。目前,任何超过 6 分钟的测试都会以标题中所述的错误结束。 “OpenQA.Selenium.WebDriverException:对远程 WebDriver 服务器的 URL http://localhost:52821/session/f88e9cd6e93e8a3ef98796aaf87d14dd/url 的 HTTP 请求在 90 秒后超时。”
但是,正在测试的页面都是实时生产网站,没有任何正在测试的内容是在本地主机上。
到目前为止,我已尝试将默认命令超时增加到各种间隔,包括 30、60、90、120 和 180 秒,这只会使测试报告错误所需的时间更长。有时测试会运行 6 分钟,有时会停止 13 分钟或介于两者之间。通常它甚至会到达测试的最后一页并在那里抛出错误。奇怪的是,如果我把页面分开,它就可以正常运行。然而,当测试以这种方式失败时,chromedriver 不会退出,页面保持打开状态,刷新事物旋转,就像等待请求一样。
我已经查看了这里和 Reddit 上的所有其他相关问题,它们似乎都自行解决了(就像它刚刚消失一样),或者做了一些解决方案,实际上并没有解决问题,但允许他们仍然进行测试。我想知道这到底是怎么回事。
我的 chrome 浏览器是最新版本:版本 100.0.4896.127 chromedriver 也是 100.*** 版本 chrome 的最新版本。我重新安装了两个并且出现同样的问题。我使用的所有 Nuget 软件包也是最新的。
我用firefox尝试了geckodriver,问题也存在。
我不确定这是否是硒问题,或者是我的测试套件设计的问题,甚至是我的电脑的问题,因为它有时会冻结。所以我将包括我认为相关的所有内容。
我一直在使用单例方法(仅供参考) 代码
设置
[SetUpFixture]
[TestFixture]
public class Setup
{
IWebDriver driver;
//Runs before ANY test is run
//provies a place to set up configs for a testing env
[OneTimeSetUp]
public void RunBeforeAllTests()
{
driver = WebDriverSingleton.GetInstance();
}
//Will run after every test has been completed
//clean up
[OneTimeTearDown]
public void RunAfterAllTests()
{
WebDriverSingleton.Terminate();
}
}
司机
public class Driver
{
public IWebDriver driver;
public Driver()
{
this.driver = WebDriverSingleton.GetInstance();
}
public void Start()
{
driver = WebDriverSingleton.GetInstance();
driver.Manage().Window.Maximize();
}
public void End()
{
driver.Close();
//WebDriverSingleton.Terminate();
}
public void GoTo(string url)
{
this.driver.Url = url;
}
public IWebElement GetElementBy(string method, string selector)
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromMilliseconds(20000));
try
{
switch (method)
{
case "tag":
return wait.Until(ExpectedConditions.ElementIsVisible(By.TagName(selector)));
case "xpath":
return wait.Until(ExpectedConditions.ElementIsVisible(By.XPath(selector)));
case "css":
return wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector(selector)));
case "id":
return wait.Until(ExpectedConditions.ElementIsVisible(By.Id(selector)));
default:
return null;
}
}catch (Exception ex)
{
Assert.Fail("FAILURE! last page: " + this.driver.Url + "\n" + ex.Message);
return null;
}
}
public string GetTextBy(string method, string selector)
{
WebDriverWait wait = new(driver, TimeSpan.FromMilliseconds(10000));
//{
// didnt seem to work :/
// PollingInterval = TimeSpan.FromSeconds(5),
//};
switch (method)
{
case "tag":
return wait.Until(ExpectedConditions.ElementIsVisible(By.TagName(selector))).Text;
case "xpath":
return wait.Until(ExpectedConditions.ElementIsVisible(By.XPath(selector))).Text;
case "css":
return wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector(selector))).Text;
case "id":
return wait.Until(ExpectedConditions.ElementIsVisible(By.Id(selector))).Text;
default:
return null;
}
}
}
单例
public sealed class WebDriverSingleton
{
private static IWebDriver instance = null;
private WebDriverSingleton() { }
public static IWebDriver GetInstance()
{
if(instance == null)
{
ChromeOptions options = new();
options.BrowserVersion = "100.0.4896.6000";
options.AddArgument("no-sandbox");
instance = new ChromeDriver(Environment.CurrentDirectory, options, TimeSpan.FromSeconds(90));
}
return instance;
}
public static void Terminate()
{
instance.Close();
instance.Quit();
instance.Dispose();
instance = null;
}
}
问题根源的测试类
[TestFixture]
public class PowerSupplyTests
{
readonly Driver driver = new Driver();
private readonly Common Common = new();
public List<ProductPage> ProductPages { get; set; }
public string TestDomain { get; set; }
public string CurrLang { get; set; }
// for now only 1 language comparison can be run at a time
public List<string> LanguagesToTest = new List<string>()
{
/*"DE","ES", */ "FR"/*, "IT"*/
};
public List<string> ProductPageListOldTechSpecTable = new List<string>()
{
"/products/industrial-power-supply/quint-1-phase-xt.shtml",
"/products/industrial-power-supply/quint-3-phase.shtml",
//"/products/industrial-power-supply/trio-3-phase.shtml"
};
public List<string> ProductPageListBasicDataTable = new List<string>()
{
"/products/industrial-din-rail-power-supplies.shtml",
};
public List<string> ProductPageListSingleProduct = new List<string>()
{
"/products/industrial-power-supply/quint-high-input.shtml",
"/products/industrial-power-supply/quint-ps-12dc-12dc-8-29050078.shtml",
"/products/industrial-power-supply/quint-ps-12dc-24dc-5-23201318.shtml",
"/products/industrial-power-supply/quint-ps-1ac-12dc-15-29046088.shtml",
"/products/industrial-power-supply/quint-ps-1ac-12dc-20-28667218.shtml",
"/products/industrial-power-supply/quint-ps-1ac-24dc-1.3-pt-29095758.shtml",
"/products/industrial-power-supply/quint-ps-1ac-24dc-1.3-sc-29045978.shtml",
"/products/industrial-power-supply/quint-ps-1ac-24dc-10-29046018.shtml",
"/products/industrial-power-supply/quint-ps-1ac-24dc-2.5-29095768.shtml",
"/products/industrial-power-supply/quint-ps-1ac-24dc-2.5-sc-29045988.shtml",
"/products/industrial-power-supply/quint-ps-1ac-24dc-20-29046028.shtml",
"/products/industrial-power-supply/quint-ps-1ac-24dc-3.5-28667478.shtml",
"/products/industrial-power-supply/quint-ps-1ac-24dc-3.8-pt-29095778.shtml",
"/products/industrial-power-supply/quint-ps-1ac-24dc-3.8-sc-29045998.shtml",
"/products/industrial-power-supply/quint-ps-1ac-24dc-40-28667898.shtml",
"/products/industrial-power-supply/quint-ps-1ac-24dc-5-29046008.shtml",
"/products/industrial-power-supply/quint-ps-1ac-48dc-10-29046118.shtml",
"/products/industrial-power-supply/quint-ps-1ac-48dc-20-28666958.shtml",//here for IT
"/products/industrial-power-supply/quint-ps-1ac-48dc-5-29046108.shtml",
"/products/industrial-power-supply/quint-ps-24dc-12dc-8-23201158.shtml",
"/products/industrial-power-supply/quint-ps-24dc-24dc-10-23200928.shtml",
"/products/industrial-power-supply/quint-ps-24dc-24dc-10-co-23205558.shtml",
"/products/industrial-power-supply/quint-ps-24dc-24dc-20-23201028.shtml",//
"/products/industrial-power-supply/quint-ps-24dc-24dc-20-co-23205688.shtml",
"/products/industrial-power-supply/quint-ps-24dc-24dc-5-23200348.shtml",
"/products/industrial-power-supply/quint-ps-24dc-24dc-5-co-23205428.shtml",
"/products/industrial-power-supply/quint-ps-24dc-48dc-5-23201288.shtml",
"/products/industrial-power-supply/quint-ps-48dc-24dc-5-23201448.shtml",
"/products/industrial-power-supply/quint-ps-48dc-48dc-5-29050088.shtml",
"/products/industrial-power-supply/quint-ps-60-72dc-24dc-10-29050098.shtml",
"/products/industrial-power-supply/quint-ps-60-72dc-24dc-10-co-29050118.shtml",
"/products/industrial-power-supply/quint-ps-96-110dc-24dc-10-29050108.shtml",
"/products/industrial-power-supply/quint-ps-96-110dc-24dc-10-co-29050128.shtml",
"/products/industrial-power-supply/step-ps-1ac-12dc-1.5-28685678.shtml",
"/products/industrial-power-supply/step-ps-1ac-12dc-1.5-fl-28685548.shtml",
"/products/industrial-power-supply/step-ps-1ac-12dc-1-28685388.shtml",
"/products/industrial-power-supply/step-ps-1ac-12dc-3-28685708.shtml",
"/products/industrial-power-supply/step-ps-1ac-12dc-5-28685838.shtml",
"/products/industrial-power-supply/step-ps-1ac-15dc-4-28686198.shtml",
"/products/industrial-power-supply/step-ps-1ac-24dc-0.5-28685968.shtml",
"/products/industrial-power-supply/step-ps-1ac-24dc-0.75-28686358.shtml",
"/products/industrial-power-supply/step-ps-1ac-24dc-0.75-fl-28686228.shtml",
"/products/industrial-power-supply/step-ps-1ac-24dc-1.75-28686488.shtml",
"/products/industrial-power-supply/step-ps-1ac-24dc-2.5-28686518.shtml",
"/products/industrial-power-supply/step-ps-1ac-24dc-3.5-29049458.shtml",
"/products/industrial-power-supply/step-ps-1ac-24dc-3.8-c2lps-28686778.shtml",
"/products/industrial-power-supply/step-ps-1ac-24dc-4.2-28686648.shtml",
"/products/industrial-power-supply/step-ps-1ac-48dc-2-28686808.shtml",//
"/products/industrial-power-supply/step-ps-1ac-5dc-16.5-28685418.shtml",
"/products/industrial-power-supply/step-ps-1ac-5dc-2-23205138.shtml",
"/products/industrial-power-supply/step-ps-48ac-24dc-0.5-28687168.shtml",
"/products/industrial-power-supply/trio-dc-dc-high-input.shtml",
"/products/industrial-power-supply/trio-ps-2g-1ac-12dc-10-29031588.shtml",
"/products/industrial-power-supply/trio-ps-2g-1ac-12dc-5-c2lps-29031578.shtml",
"/products/industrial-power-supply/trio-ps-2g-1ac-24dc-10-29031498.shtml",
"/products/industrial-power-supply/trio-ps-2g-1ac-24dc-10-b+d-29031458.shtml",
"/products/industrial-power-supply/trio-ps-2g-1ac-24dc-20-29031518.shtml",
"/products/industrial-power-supply/trio-ps-2g-1ac-24dc-3-c2lps-29031478.shtml",
"/products/industrial-power-supply/trio-ps-2g-1ac-24dc-5-29031488.shtml",
"/products/industrial-power-supply/trio-ps-2g-1ac-24dc-5-b+d-29031448.shtml",
"/products/industrial-power-supply/trio-ps-2g-1ac-48dc-10-29031608.shtml",
"/products/industrial-power-supply/trio-ps-2g-1ac-48dc-5-29031598.shtml",
"/products/industrial-power-supply/uno-2-phase.shtml",
"/products/industrial-power-supply/uno-dc-dc.shtml",
"/products/industrial-power-supply/uno-ps-1ac-12dc-100w-29029978.shtml",
"/products/industrial-power-supply/uno-ps-1ac-12dc-30w-29029988.shtml",
"/products/industrial-power-supply/uno-ps-1ac-15dc-100w-29030028.shtml",
"/products/industrial-power-supply/uno-ps-1ac-15dc-30w-29030008.shtml",
"/products/industrial-power-supply/uno-ps-1ac-15dc-55w-29030018.shtml",
"/products/industrial-power-supply/uno-ps-1ac-24dc-100w-29029938.shtml",
"/products/industrial-power-supply/uno-ps-1ac-24dc-150w-29043768.shtml",
"/products/industrial-power-supply/uno-ps-1ac-24dc-240w-29043728.shtml",
"/products/industrial-power-supply/uno-ps-1ac-24dc-30w-29029918.shtml",
"/products/industrial-power-supply/uno-ps-1ac-24dc-60w-29029928.shtml",
"/products/industrial-power-supply/uno-ps-1ac-24dc-90w-c2lps-29029948.shtml",
"/products/industrial-power-supply/uno-ps-1ac-48dc-100w-29029968.shtml",
"/products/industrial-power-supply/uno-ps-1ac-48dc-60w-29029958.shtml",
"/products/industrial-power-supply/uno-ps-1ac-5dc-25w-29043748.shtml",
"/products/industrial-power-supply/uno-ps-1ac-5dc-40w-29043758.shtml"
};
[SetUp]
public void Start()
{
driver.Start();
ProductPages = new List<ProductPage>();
}
[Test]
public void TestAllPages()
{
LanguagesToTest.ForEach((lang) =>
{
CurrLang = lang;
switch (lang)
{
case "DE":
TestDomain = Common.GermanDomain;
break;
case "ES":
TestDomain = Common.SpanishDomain;
break;
case "FR":
TestDomain = Common.FrenchDomain;
break;
case "IT":
TestDomain = Common.ItalianDomain;
break;
}
ProductPageListBasicDataTable.ForEach((p) =>
{
ProductPage newPage = new ProductPage(driver, p);
TestDocumentationTab(newPage);
TestOrderDetailsTabBasicTable(newPage);
});
ProductPageListOldTechSpecTable.ForEach((p) =>
{
ProductPage newPage = new ProductPage(driver, p);
TestDocumentationTab(newPage);
TestOrderDetailsTabOldSpecTable(newPage);
});
ProductPageListSingleProduct.ForEach((p) =>
{
ProductPage newPage = new ProductPage(driver, p);
TestDocumentationTab(newPage);
TestOrderDetailTabSingleProduct(newPage);
});
});
}
public void TestDocumentationTab(ProductPage productPage)
{
productPage.GoToProduct(Common.EnglishDomain);
productPage.OpenDocumentationTab();
string enSrc = productPage.CaptureIframeSrc("idoc");
enSrc = enSrc.Substring(enSrc.IndexOf("products"));
productPage.GoToProduct(TestDomain);
productPage.OpenDocumentationTab();
string comparisonSrc = productPage.CaptureIframeSrc("idoc");
comparisonSrc = comparisonSrc.Substring(comparisonSrc.IndexOf("products"));
if (!enSrc.Equals(comparisonSrc))
Assert.Fail("Page " + productPage.PageUrl + " documentation sources do not match! \n "+ enSrc + "\n" + comparisonSrc + " failure found in lang: " + CurrLang);
}
public void TestOrderDetailsTabBasicTable(ProductPage productPage)
{
List<Product> enProducts = new List<Product>();
List<Product> comparisonProducts = new List<Product>();
productPage.GoToProduct(Common.EnglishDomain);
productPage.OpenOrderingDetailsTab();
enProducts = productPage.OrderDetailsTabModel.GetProductsFromBasicDataTable();
productPage.GoToProduct(TestDomain);
productPage.OpenOrderingDetailsTab();
comparisonProducts = productPage.OrderDetailsTabModel.GetProductsFromBasicDataTable();
if (enProducts.Count != comparisonProducts.Count)
Assert.Fail("Product Table Quantites do not match!");
for (int i = 0; i < enProducts.Count; i++)
{
if (!enProducts[i].Equals(comparisonProducts[i]))
Assert.Fail("Product Tables do not match! \n" + "Failure occurred on page: " + productPage.PageUrl + "\nIn Lang: " + CurrLang);
}
}
public void TestOrderDetailsTabOldSpecTable(ProductPage productPage)
{
List<Product> enProducts = new List<Product>();
List<Product> testProducts = new List<Product>();
productPage.GoToProduct(Common.EnglishDomain);
productPage.OpenOrderingDetailsTab();
enProducts = productPage.OrderDetailsTabModel.GetProductsFromTechSpecDataTable();
productPage.GoToProduct(TestDomain);
productPage.OpenOrderingDetailsTab();
testProducts = productPage.OrderDetailsTabModel.GetProductsFromTechSpecDataTable();
if (enProducts.Count != testProducts.Count)
Assert.Fail("Product Table Quantites do not match!");
for (int i = 0; i < enProducts.Count; i++)
{
if (!enProducts[i].Equals(testProducts[i]))
Assert.Fail( CurrLang + " Product Tables do not match!");
}
}
public void TestOrderDetailTabSingleProduct(ProductPage productPage)
{
Product enProduct = new Product();
Product testProducts = new Product();
productPage.GoToProduct(Common.EnglishDomain);
productPage.OpenOrderingDetailsTab();
enProduct = productPage.OrderDetailsTabModel.GetSingleProductFromTab();
productPage.GoToProduct(TestDomain);
productPage.OpenOrderingDetailsTab();
testProducts = productPage.OrderDetailsTabModel.GetSingleProductFromTab();
Assert.IsNotNull(enProduct.productId);
Assert.IsNotNull(testProducts.productId);
if (!enProduct.Equals(testProducts))
Assert.Fail("Products Do Not Match!\nEN: " + enProduct.productId[0] + "\n" + CurrLang + ": " + testProducts.productId[0]);
}
[TearDown]
public void End()
{
driver.End();
}
}
最后是错误日志
TestAllPages
Source: powerSupplyTests.cs line 125
Duration: 11.1 min
Message:
OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://localhost:52821/session/f88e9cd6e93e8a3ef98796aaf87d14dd/url timed out after 90 seconds.
----> System.Threading.Tasks.TaskCanceledException : The request was canceled due to the configured HttpClient.Timeout of 90 seconds elapsing.
----> System.TimeoutException : The operation was canceled.
----> System.Threading.Tasks.TaskCanceledException : The operation was canceled.
----> System.IO.IOException : Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
----> System.Net.Sockets.SocketException : The I/O operation has been aborted because of either a thread exit or an application request.
TearDown : OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://localhost:52821/session/f88e9cd6e93e8a3ef98796aaf87d14dd/window timed out after 90 seconds.
----> System.Threading.Tasks.TaskCanceledException : The request was canceled due to the configured HttpClient.Timeout of 90 seconds elapsing.
----> System.TimeoutException : The operation was canceled.
----> System.Threading.Tasks.TaskCanceledException : The operation was canceled.
----> System.IO.IOException : Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
----> System.Net.Sockets.SocketException : The I/O operation has been aborted because of either a thread exit or an application request.
Stack Trace:
HttpCommandExecutor.Execute(Command commandToExecute)
DriverServiceCommandExecutor.Execute(Command commandToExecute)
WebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
WebDriver.set_Url(String value)
Driver.GoTo(String url) line 36
ProductPage.GoToProduct(String baseUrl) line 48
PowerSupplyTests.TestDocumentationTab(ProductPage productPage) line 172
PowerSupplyTests.<TestAllPages>b__19_3(String p) line 160
List`1.ForEach(Action`1 action)
PowerSupplyTests.<TestAllPages>b__19_0(String lang) line 157
List`1.ForEach(Action`1 action)
PowerSupplyTests.TestAllPages() line 127
--TaskCanceledException
HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
HttpCommandExecutor.MakeHttpRequest(HttpRequestInfo requestInfo)
HttpCommandExecutor.Execute(Command commandToExecute)
--TimeoutException
--TaskCanceledException
HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
--IOException
AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
AwaitableSocketAsyncEventArgs.GetResult(Int16 token)
HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
--SocketException
--TearDown
HttpCommandExecutor.Execute(Command commandToExecute)
DriverServiceCommandExecutor.Execute(Command commandToExecute)
WebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
WebDriver.Close()
Driver.End() line 31
PowerSupplyTests.End() line 237
--TaskCanceledException
HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
HttpCommandExecutor.MakeHttpRequest(HttpRequestInfo requestInfo)
HttpCommandExecutor.Execute(Command commandToExecute)
--TimeoutException
--TaskCanceledException
HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
--IOException
AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
AwaitableSocketAsyncEventArgs.GetResult(Int16 token)
HttpConnection.FillAsync(Boolean async)
HttpConnection.ReadNextResponseHeaderLineAsync(Boolean async, Boolean foldedHeadersAllowed)
HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
--SocketException
这个行为可能是在新的(第 100 个)版本的 Chrome 中引入的。尝试使用旧版本的 Chrome 和 chromedriver。
我觉得我已经找到了一些可以为某人工作的解决方案。 因此,我使用 TeamCity Agent 使用 Selenium 运行了 100 多个测试用例。几乎每次至少有一个测试因这样的错误而失败:
09:30:12 OpenQA.Selenium.WebDriverException:未知 向远程发送 HTTP 请求时遇到异常 URL 的 WebDriver 服务器 http://localhost:10458/session/e050c5112562c1539c7518353fa3cce2/element。 异常消息是:无法建立连接,因为 目标机主动拒绝。 (本地主机:10458)09:30:12
----> System.Net.Http.HttpRequestException :无法建立连接,因为目标计算机主动拒绝它。 (本地主机:10458) 09:30:12 ----> System.Net.Sockets.SocketException:无连接 可以制作,因为目标机器主动拒绝。
我检查了运行测试的服务器上的代理、防火墙、大多数情况下设置的配置,人们将其描述为修复。例如:
"--no-sandbox",
"--proxy-server='direct://'",
"--proxy-bypass-list=*",
但这并没有解决任何问题。所以当时我使用的是 .NET 6.0 和最新的 chromedriver ChromeDriver 113.0.5672.63。
有效的是 .NET 6.0 降级到 .NET 5.0