You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迁移至.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 14:50:57