迁移至.NET 6.0后Selenium自动化测试性能大幅下降求助
Selenium自动化测试从.NET Framework 4.8.1迁移到.NET 6.0后性能骤降的排查与解决思路
问题概述
将Selenium自动化测试项目从.NET Framework 4.8.1迁移至.NET 6.0后,测试执行时长显著增加,单个TestFixture的耗时从26分钟升至56分钟。
已完成的排查
- 排除Win10下
HttpWebRequest解析localhost触发1秒超时的问题,测试框架绑定的是Azure预发布环境,未使用localhost。 - 在代码、NuGet包版本、测试环境完全一致的前提下,性能分析显示WebDriver请求平均慢2-5倍,其中.NET 6.0在WebDriverWait相关操作上的耗时尤为突出。
.NET性能分析细节
项目中封装了WebElement类处理异常和显式等待,以下是核心方法的执行耗时对比(注释中为.NET 6.0 / .NET Framework 4.8.1的耗时):
Click()方法
public bool Click(Driver driver) { InitWait(driver); //.NET - 415ms, Framework - 28ms _log.Debug($"Trying to click {_locator}"); try { el = wait.Until(ExpectedConditions.ElementToBeClickable(_locator)); //.NET - 266ms, Framework - 20ms el.Click(); //.NET - 49ms, Framework - 39ms return true; } catch (Exception e) { if (e is ElementClickInterceptedException) { ScrollToElementJS(driver); el.Click(); return true; } else { Fail($"Can't click element '{_locator}'", e); throw; } } }
InitWait()方法
private protected void InitWait(Driver driver, int seconds = 30) { if (wait == null) wait = new WebDriverWait(driver.webDriverInstance, TimeSpan.FromSeconds(seconds)); else wait.Timeout = TimeSpan.FromSeconds(seconds); wait.IgnoreExceptionTypes(typeof(NoSuchElementException), typeof(StaleElementReferenceException)); WaitUntilLoadingCompletes(driver); //.NET - 307ms, Framework - 90ms }
WaitUntilLoadingCompletes()方法
public void WaitUntilLoadingCompletes(Driver driver) { var wait = new WebDriverWait(driver.webDriverInstance, _thirty); wait.IgnoreExceptionTypes(typeof(NoSuchElementException), typeof(StaleElementReferenceException)); Element spinner = new Element(By.XPath(Config.spinnerXPath)); Element spinnerBar = new Element(By.XPath("//div[@id='loading-bar']")); Element divOverlay = new Element(By.XPath("//div[@class='overlay']")); try { wait.Until(ExpectedConditions.InvisibilityOfElementLocated(spinner._locator)); //.NET - 124ms, Framework - 20ms wait.Until(ExpectedConditions.InvisibilityOfElementLocated(spinnerBar._locator)); //.NET - 97ms, Framework - 10ms wait.Until(ExpectedConditions.InvisibilityOfElementLocated(divOverlay._locator)); //.NET - 102ms, Framework - 55ms } catch (Exception e) { Fail($"One of the loaders at '{_locator}' is visible after {wait.Timeout.ToPrettyFormat()}", e); } }
依赖包版本
<PackageReference Include="DotNetSeleniumExtras.WaitHelpers" Version="3.11.0" /> <PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> <PackageReference Include="NUnit" Version="3.13.3" /> <PackageReference Include="NUnit.ConsoleRunner" Version="3.16.3" /> <PackageReference Include="NUnit3TestAdapter" Version="4.5.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" /> <PackageReference Include="Selenium.Support" Version="4.11.0" /> <PackageReference Include="Selenium.WebDriver" Version="4.11.0" /> <PackageReference Include="WebDriverManager" Version="2.17.0" />
排查思路与解决方案
- 调整WebDriverWait轮询间隔:.NET 6下WebDriverWait默认PollingInterval可能偏长,显式设置为更短的间隔(如100ms),减少等待过程中的空转时间。示例:
wait.PollingInterval = TimeSpan.FromMilliseconds(100); - 升级Selenium相关包:当前使用的Selenium 4.11.0可能存在.NET 6适配的性能问题,尝试升级到最新稳定版(如4.15.0及以上),新版本通常会修复跨平台/框架的兼容性问题。
- 优化加载等待逻辑:将
WaitUntilLoadingCompletes中的串行等待改为并行检查,同时判断三个加载元素的不可见状态,减少总等待时长。可以自定义等待条件:wait.Until(driver => !spinner.IsDisplayed(driver) && !spinnerBar.IsDisplayed(driver) && !divOverlay.IsDisplayed(driver) ); - 调整.NET 6 HTTP客户端配置:Selenium在.NET 6中使用的HttpClient默认配置与.NET Framework不同,可自定义WebDriver的HttpClientFactory,调整连接池大小、超时时间等参数,提升请求效率。
- 检查GC行为:.NET 6的GC策略与.NET Framework差异较大,可在测试项目的
runtimeconfig.json中启用Server GC或调整GC堆参数,减少GC停顿对测试执行的影响:{ "runtimeOptions": { "configProperties": { "System.GC.Server": true, "System.GC.HeapCount": 4 } } } - 验证WebDriver与浏览器兼容性:确保ChromeDriver/GeckoDriver等WebDriver版本与测试使用的浏览器版本完全匹配,版本不兼容可能导致请求延迟或异常。
内容的提问来源于stack exchange,提问作者pwrngr
相关产品推荐
相关产品推荐

