Selenium Java实现WebDriver线程安全 解决并行测试失败问题
解决方案
你的问题核心是没有正确用ThreadLocal管理WebDriver的线程隔离——虽然创建了ThreadLocal实例,但依然在使用全局的driver变量,导致多线程共享同一个WebDriver实例,并行运行时互相干扰。
以下是完整的修正方案:
1. 修改BaseClass,用ThreadLocal完全管理WebDriver
把原来的全局driver替换为ThreadLocal实例,所有操作都通过ThreadLocal来获取和销毁WebDriver:
import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.edge.EdgeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import io.github.bonigarcia.wdm.WebDriverManager; import java.io.FileInputStream; import java.io.IOException; import java.time.Duration; import java.util.Properties; public class BaseClass { // 用ThreadLocal存储WebDriver,保证每个线程有独立实例 private ThreadLocal<WebDriver> threadSafeDriver = new ThreadLocal<>(); public HomePage homePage; public WebDriver setup() throws IOException { Properties prop = new Properties(); FileInputStream fis = new FileInputStream( System.getProperty("user.dir") + "\\src\\main\\resource\\GlobalData.Properties"); prop.load(fis); String browserName = System.getProperty("browser") != null ? System.getProperty("browser") : prop.getProperty("browser"); WebDriver driver = null; if (browserName.contains("chrome")) { WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(); } else if (browserName.contains("edge")) { WebDriverManager.edgedriver().setup(); driver = new EdgeDriver(); } else if (browserName.contains("firefox")) { WebDriverManager.firefoxdriver().setup(); driver = new FirefoxDriver(); } driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); driver.manage().window().maximize(); // 将当前线程的driver存入ThreadLocal threadSafeDriver.set(driver); return threadSafeDriver.get(); } @BeforeMethod public HomePage LaunchApplication() throws IOException { // 从ThreadLocal获取当前线程的driver WebDriver driver = setup(); homePage = new HomePage(driver); homePage.goTo(); return homePage; } @AfterMethod public void tearDown() { // 获取当前线程的driver并关闭 WebDriver driver = threadSafeDriver.get(); if (driver != null) { driver.quit(); // 用quit而不是close,确保彻底销毁浏览器进程 // 移除ThreadLocal中的实例,避免内存泄漏 threadSafeDriver.remove(); } } }
2. 确保TestNG的并行配置正确
在testng.xml里配置方法级并行,指定线程数:
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" > <suite name="Test Suite" parallel="methods" thread-count="3"> <test name="All Tests"> <classes> <class name="com.yourpackage.TestCases"/> </classes> </test> </suite>
关键修改点说明
- 移除了全局的
public WebDriver driver,改用ThreadLocal<WebDriver>存储每个线程独立的WebDriver实例 - setup方法中创建driver后,通过
threadSafeDriver.set(driver)绑定到当前线程 - 所有需要使用driver的地方,都通过
threadSafeDriver.get()获取当前线程的实例 - tearDown中不仅关闭浏览器,还调用
threadSafeDriver.remove()清理ThreadLocal,避免内存泄漏 - 把
driver.close()改为driver.quit(),确保浏览器进程完全终止,避免残留进程影响并行
内容的提问来源于stack exchange,提问作者Karteek
相关产品推荐
相关产品推荐

