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

Azure DevOps托管代理并行运行Chromedriver时抛出进程占用异常

问题核心异常
Error: Exception has been thrown by the target of an invocation. -> The process cannot access the file 'D:\a_temp\TestResults\Chrome\102.0.5005.61\X64\chromedriver.exe' because it is being used by another process.

该异常仅在Azure DevOps流水线并行执行SpecRun.SpecFlow测试时触发,本地多线程运行无复现,本质是跨测试进程共享固定路径的chromedriver.exe文件,触发文件读写/运行锁争抢:本地多线程测试默认运行在单个测试进程内,chromedriver的下载、启动、销毁由同一个进程托管,且本地驱动缓存一般提前下载完成,不会触发运行时写文件逻辑;Azure DevOps流水线的并行测试如果是多进程级并行,所有进程默认访问agent上同一个共享临时目录下的驱动文件,多个进程同时触发驱动下载校验、启动逻辑时就会抛出占用异常。

排查思路
  • 检查SpecRun配置:打开项目下的.srprofile文件,查看<Execution>节点的testIsolation和parallelScope配置,确认是否开启了进程级隔离(testIsolation="Process"),该模式下每个测试线程会启动独立的测试进程,每个进程都会独立初始化WebDriver逻辑。
  • 检查Azure DevOps测试任务配置:查看Visual Studio Test(或dotnet test)任务是否开启了测试切片并行分发,若开启多切片并行,每个切片是独立运行的测试进程,共享agent机器的全局临时目录。
  • 检查WebDriver初始化逻辑:确认项目使用的chromedriver管理方式(Selenium.WebDriver.ChromeDriver NuGet包/WebDriverManager.Net等自动下载组件),是否未自定义驱动缓存路径,默认使用了全局共享的临时目录,且初始化时存在重复校验、覆盖下载驱动的逻辑。
  • 检查agent进程残留:确认流水线运行前是否存在上一次任务未正常退出的chromedriver.exe进程,提前占住了对应路径的文件句柄。
修复方案
  • 为每个并行测试实例分配独立的chromedriver缓存目录
    若使用自动驱动管理组件,初始化驱动时不要使用默认共享路径,为每个执行实例生成唯一的临时目录存放驱动,从根源避免跨进程文件争抢:
    // 为当前测试实例生成唯一驱动目录
    var driverCachePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"));
    Directory.CreateDirectory(driverCachePath);
    
    // 初始化驱动时指定独立目录(以WebDriverManager.Net为例)
    new DriverManager().SetUpDriver(new ChromeConfig(), version: "102.0.5005.61", architecture: Architecture.X64, driverCachePath);
    var chromeDriver = new ChromeDriver(driverCachePath);
    
    若使用Selenium.WebDriver.ChromeDriver NuGet包,修改项目构建配置,禁止将chromedriver.exe输出到全局统一的TestResults目录,改为输出到每个测试进程独立的生成目录。
  • 调整SpecRun并行隔离级别
    无特殊进程隔离需求的场景下,修改.srprofile配置为线程级并行,减少跨进程锁冲突:
    <Execution 
      parallelScope="Feature" 
      testThreadCount="根据agent配置设置合理并行数" 
      testIsolation="Thread"
    />
    
    若必须使用进程级隔离,必须搭配上述独立驱动目录方案使用
  • 流水线侧提前部署驱动、清理残留进程
    • 在测试任务执行前增加PowerShell步骤,强制清理残留的chromedriver进程:
      Get-Process chromedriver -ErrorAction SilentlyContinue | Stop-Process -Force
      
    • 提前下载对应版本的chromedriver到流水线独有的非共享路径(可使用$(Agent.TempDirectory)\$(Build.BuildId)这类每次运行唯一的内置变量拼接路径),测试运行时直接指向该预下载路径,同时加环境变量判断禁用测试运行时的驱动自动下载、版本校验逻辑,避免运行时多个进程同时读写驱动文件。
  • 配置测试任务的切片隔离
    若使用Azure DevOps多切片并行,配置每个测试切片使用独立的临时目录,在测试任务的环境变量中为每个切片设置独立的TEMP、TMP路径,基于切片ID生成唯一值,避免所有切片共享同一个临时目录。

内容的提问来源于stack exchange,提问作者benm912

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:03:27