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

Selenium基于ThreadLocal并行测试出现首个空白浏览器问题如何修复

问题根因

首个浏览器空白的核心问题是WebDriverFactory中静态ThreadLocal实例被反复覆盖,首个测试线程创建的WebDriver实例后续无法被正确访问,导致浏览器没有收到执行指令处于空白状态。

存在的问题点

  • 每次调用setDriver都会创建新的ThreadLocal实例覆盖静态变量,旧ThreadLocal中存储的首个线程WebDriver副本会丢失
  • setDriver、getDriver添加了不必要的synchronized修饰,既拖慢并行效率,又放大了多线程下实例覆盖的问题
  • closeBrowser销毁driver后没有调用ThreadLocal.remove(),存在内存泄漏,同线程复用场景下还会拿到已销毁的无效driver
  • 仅Chrome分支调用了prepareBrowser配置,Firefox启动后没有窗口最大化、超时等配置
  • 类设计冗余:BasePage继承WorldHelper会触发重复初始化WebDriver逻辑,容易拿到空值或错误实例
  • WorldHelper提前缓存WebDriver实例,若实例化时机早于@Before的setDriver调用,会直接拿到空值

修复代码

1. WebDriverFactory修改

public class WebDriverFactory {
    // 全局唯一ThreadLocal实例,禁止反复赋值
    private static final ThreadLocal<WebDriver> driver = new ThreadLocal<>();

    // 移除不必要的synchronized,ThreadLocal本身线程安全
    public static void setDriver(String browser) {
        WebDriver webDriver;
        switch (browser) {
            case "chrome":
                WebDriverManager.chromedriver().setup();
                webDriver = new ChromeDriver(BrowserOptions.getChromeOptions());
                break;
            case "fireFox":
                WebDriverManager.firefoxdriver().setup();
                webDriver = new FirefoxDriver(BrowserOptions.getFirefoxOptions());
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + browser);
        }
        driver.set(webDriver);
        // 所有浏览器统一执行配置初始化
        prepareBrowser();
    }

    private static void prepareBrowser() {
        WebDriver currentDriver = getDriver();
        currentDriver.manage().window().maximize();
        currentDriver.manage().deleteAllCookies();
        currentDriver.manage().timeouts().pageLoadTimeout(15, TimeUnit.SECONDS);
        currentDriver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
    }

    // 移除不必要的synchronized
    public static WebDriver getDriver() {
        return driver.get();
    }

    public static void closeBrowser() {
        WebDriver currentDriver = getDriver();
        if (currentDriver != null) {
            currentDriver.quit();
        }
        // 清除当前线程的ThreadLocal副本,避免泄漏和脏数据
        driver.remove();
    }
}

2. 类继承结构修复

删除BasePage对WorldHelper的继承,避免重复初始化逻辑:

public class BasePage {
    protected final WebDriver webDriver;

    public BasePage(WebDriver driver) {
        this.webDriver = driver;
    }
}

3. WorldHelper修改

移除提前缓存的WebDriver,每次调用时从工厂取最新实例,避免拿到空值:

public class WorldHelper {
    private BasePage basePage;
    private SamplePage samplePage;

    public WebDriver getWebDriver() {
        return WebDriverFactory.getDriver();
    }

    public SamplePage getSamplePage() {
        if(samplePage != null)
            return samplePage;
        samplePage = PageFactory.initElements(getWebDriver(), SamplePage.class);
        return samplePage;
    }
}

修改完成后并行执行测试,所有浏览器都会正常接收执行指令,不会再出现首个浏览器空白的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 03:48:01