Selenium C# WebDriver负载测试仅首个实例正常其余报错求助
解决Selenium C#多实例负载测试时Web元素识别失败的问题
看起来你遇到的核心问题是多实例并行运行时,静态共享的WebDriver实例导致资源冲突,加上ChromeDriver服务端口未独立分配,最终出现连接被拒绝的错误。下面我会一步步分析问题根源,并给出具体的修复方案:
问题根源分析
- 静态Driver实例的共享冲突:你的代码中
Base.Driver是静态变量,在多实例并行测试时,所有测试会共用同一个Driver实例——第一个测试占用后,后续测试无法创建新的独立Driver,自然无法正常操作页面元素。 - ChromeDriver服务未独立化:默认创建ChromeDriver时,可能会复用端口或服务进程,当多个实例尝试使用同一服务时,就会出现"目标机器主动拒绝连接"的Socket异常。
具体修复步骤
1. 移除静态Driver,改为实例级Driver
把Base类中的静态Driver改为实例属性,确保每个测试类实例拥有独立的Driver,同时为每个实例绑定独立的ChromeDriver服务:
public class Base { public IWebDriver Driver { get; private set; } private ChromeDriverService _chromeService; // 管理独立的Chrome服务进程 public IWebDriver StartDriver(AvDriver chosenDriver) { switch (chosenDriver) { case AvDriver.Chrome: // 创建独立的ChromeDriver服务,自动分配空闲端口 _chromeService = ChromeDriverService.CreateDefaultService(_driversPath); _chromeService.Start(); // 可选:添加独立用户目录,避免会话/缓存冲突 var chromeOptions = new ChromeOptions(); chromeOptions.AddArgument($"--user-data-dir=C:\\Temp\\ChromeTestProfiles\\{Guid.NewGuid()}"); Driver = new ChromeDriver(_chromeService, chromeOptions); break; case AvDriver.Firefox: var firefoxService = FirefoxDriverService.CreateDefaultService(_driversPath); firefoxService.Start(); Driver = new FirefoxDriver(firefoxService); break; // Edge、Safari的处理逻辑类似,确保每个实例对应独立服务 default: _chromeService = ChromeDriverService.CreateDefaultService(_driversPath); _chromeService.Start(); Driver = new ChromeDriver(_chromeService); break; } Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10); Driver.Manage().Window.Maximize(); return Driver; } public void QuitDriver() { // 先关闭Driver,再停止对应的服务进程,避免资源泄漏 Driver?.Quit(); _chromeService?.Stop(); } }
2. 修改测试类,使用实例级Base对象
让每个测试实例初始化自己的Base对象,彻底避免跨实例的资源共享:
namespace LoadWebTestPOC { [TestClass] public class WebTestM { public string user = "Administrator"; public string password = "*******"; private Base _testBase; // 每个测试实例专属的Base对象 [TestInitialize] public void SetupTest() { _testBase = new Base(); Installer.SetUpEnv(_testBase); } [TestCleanup] public void TeardownTest() { _testBase.QuitDriver(); } [TestMethod] public void LoginWithCredentials() { // 所有页面操作都传入当前实例的Driver LoginModule.NavigateTo(_testBase.Driver); LoginModule.LoginWithCredentials(_testBase.Driver, user, password); var loggedUserTitle = CoreOperation.GetAttributeValue(_testBase.Driver, LoginModuleLocators.iconLogedUser, "title"); NUnit.Framework.Assert.AreEqual(user, loggedUserTitle); } } }
3. 调整工具类,接收Driver参数
修改Installer、LoginModule、CoreOperation等工具类,让它们依赖传入的Driver实例,而非静态共享的Driver:
public static class Installer { public const string CHROME = "CHROME"; public static void SetUpEnv(Base testBase) { string driverType = CHROME; SetupLocal(testBase, driverType); } public static void SetupLocal(Base testBase, string driverType) { switch (driverType) { case "CHROME": testBase.StartDriver(AvDriver.Chrome); break; case "FIREFOX": testBase.StartDriver(AvDriver.Firefox); break; // 其他浏览器分支逻辑 default: testBase.StartDriver(AvDriver.Chrome); break; } } } public static class LoginModule { public static void NavigateTo(IWebDriver driver) { driver.Navigate().GoToUrl("你的登录页面URL"); } public static void LoginWithCredentials(IWebDriver driver, string username, string pwd) { // 使用传入的Driver操作页面元素 driver.FindElement(LoginModuleLocators.usernameInput).SendKeys(username); driver.FindElement(LoginModuleLocators.passwordInput).SendKeys(pwd); driver.FindElement(LoginModuleLocators.loginButton).Click(); } } public static class CoreOperation { public static string GetAttributeValue(IWebDriver driver, By locator, string attribute) { return driver.FindElement(locator).GetAttribute(attribute); } }
额外注意事项
- 版本匹配:确保ChromeDriver版本和本地Chrome浏览器版本完全一致,版本不兼容也可能引发奇怪的连接异常。
- 资源释放:测试清理时一定要同时关闭Driver和对应的服务进程,避免残留进程占用端口或系统资源。
- 重试机制:如果负载测试时偶尔出现初始化失败,可以在
StartDriver方法中添加简单的重试逻辑,比如捕获异常后重试1-2次。
内容的提问来源于stack exchange,提问作者ikhlaque mohammad
相关产品推荐
相关产品推荐

