IIS部署Selenium测试时ChromeDriver意外生成多实例问题如何解决
问题排查与解决方案
问题复现背景
我是Selenium新手,还在学习阶段,如果问题表述不够专业还请谅解。
我们尝试通过IIS在指定机器上运行Selenium测试。
本地运行代码时一切正常,但发布到目标机器后,仅执行一次任务就会在任务管理器中出现2个ChromeDriver实例,运行状态极不稳定:有时会关闭其中一个实例,有时两个都不关闭,偶尔也会出现两个实例都正常关闭、程序运行无误的情况,暂时无法定位造成该不稳定问题的原因。
原运行代码
private IWebDriver _driver; [Route("/Test_SignIn")] public IActionResult Test_SignIn(string environment = "development") { string response = "Failed"; try { string outPutDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); _driver = new ChromeDriver(outPutDirectory); if (environment == "production") { _driver.Navigate().GoToUrl(productionUrl); } else { _driver.Navigate().GoToUrl(developmentUrl); } By userNameFieldLocator = By.Id("AccountUserName"); WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(30)); wait.Until(ExpectedConditions.ElementIsVisible(userNameFieldLocator)); _waitForLoaderToFinish(); IWebElement userNameField = _driver.FindElement(userNameFieldLocator); IWebElement passwordField = _driver.FindElement(By.Id("AccountPassword")); IWebElement signInButton = _driver.FindElement(By.XPath("//button[contains(text(), 'Sign In')]")); userNameField.SendKeys(_username); passwordField.SendKeys(_password); signInButton.Click(); By dashboardLocator = By.Id("portalBanner_EmployeeName"); wait.Until(ExpectedConditions.ElementIsVisible(dashboardLocator)); IWebElement dashboard = _driver.FindElement(dashboardLocator); response = "Success"; } catch (Exception ex) { response = ex.Message; } _driver.Close(); _driver.Quit(); return Json(response); } private string _waitForLoaderToFinish() { try { new WebDriverWait(_driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.InvisibilityOfElementLocated(By.Id("loader-wrapper"))); return null; } catch (TimeoutException e) { return $"{e.Message}"; } }
修复方案
- 移除类级别全局
_driver变量,改为方法内局部变量,避免IIS并发请求下变量被覆盖导致旧实例失去引用无法释放。 - 将driver释放逻辑移入
finally块,确保无论请求执行成功还是抛出异常,都能正常回收进程。 - 新增Chrome启动适配参数,适配服务器无UI运行场景,减少进程异常概率。
- 新增
Dispose调用,主动释放非托管资源。
修复后核心代码示例
[Route("/Test_SignIn")] public IActionResult Test_SignIn(string environment = "development") { string response = "Failed"; IWebDriver driver = null; try { string outPutDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // 配置Chrome启动参数 var options = new ChromeOptions(); options.AddArgument("--headless=new"); options.AddArgument("--no-sandbox"); options.AddArgument("--disable-dev-shm-usage"); options.AddArgument("--disable-gpu"); options.LeaveBrowserRunning = false; driver = new ChromeDriver(outPutDirectory, options); if (environment == "production") { driver.Navigate().GoToUrl(productionUrl); } else { driver.Navigate().GoToUrl(developmentUrl); } By userNameFieldLocator = By.Id("AccountUserName"); WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); wait.Until(ExpectedConditions.ElementIsVisible(userNameFieldLocator)); _waitForLoaderToFinish(driver); IWebElement userNameField = driver.FindElement(userNameFieldLocator); IWebElement passwordField = driver.FindElement(By.Id("AccountPassword")); IWebElement signInButton = driver.FindElement(By.XPath("//button[contains(text(), 'Sign In')]")); userNameField.SendKeys(_username); passwordField.SendKeys(_password); signInButton.Click(); By dashboardLocator = By.Id("portalBanner_EmployeeName"); wait.Until(ExpectedConditions.ElementIsVisible(dashboardLocator)); IWebElement dashboard = driver.FindElement(dashboardLocator); response = "Success"; } catch (Exception ex) { response = ex.Message; } finally { if (driver != null) { driver.Close(); driver.Quit(); driver.Dispose(); } } return Json(response); } // _waitForLoaderToFinish同步修改为接收driver参数,不依赖全局变量 private string _waitForLoaderToFinish(IWebDriver driver) { try { new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.InvisibilityOfElementLocated(By.Id("loader-wrapper"))); return null; } catch (TimeoutException e) { return $"{e.Message}"; } }
额外注意事项
- 确保IIS运行站点的应用程序池身份有足够的权限访问Chrome和ChromeDriver的执行文件,权限不足也会导致进程启动异常无法受控。
- 确保服务器上安装的Chrome版本和使用的ChromeDriver版本完全匹配,版本不兼容会出现各种非预期异常。
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

