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

Selenium单例模式下并行执行测试用例失败问题及解决

解决Selenium单例Driver并行执行的问题

你遇到的问题根源很明确:当前用的是传统全局单例模式,这种模式在多线程并行时,所有测试线程会共享同一个Driver实例,自然只会打开一个浏览器,测试用例还会互相干扰。要实现并行执行,核心是让每个线程拥有独立的Driver实例,这时候用ThreadLocal改造单例类就可以解决问题。

改造后的线程安全单例类

我们用ThreadLocal来存储每个线程专属的Utilities实例,这样每个测试线程都会拿到自己的Driver,互不影响。改造后的代码如下:

public class SingletonDesignPattern {
    // 用ThreadLocal存储每个线程独有的Utilities实例
    private static final ThreadLocal<Utilities> threadLocalInstance = new ThreadLocal<>();

    // 私有构造方法,禁止外部直接实例化
    private SingletonDesignPattern() {}

    // 获取当前线程专属的实例
    public static Utilities getInstance() {
        Utilities instance = threadLocalInstance.get();
        if (instance == null) {
            // 每个线程首次调用时,创建属于自己的Utilities(包含Driver)实例
            instance = new Utilities();
            threadLocalInstance.set(instance);
        }
        return instance;
    }

    // 提供清理方法,测试结束后移除当前线程的实例,避免内存泄漏
    public static void cleanInstance() {
        threadLocalInstance.remove();
    }
}

测试类中的使用方式

在测试类里,每次通过改造后的单例类获取Driver,并且在测试方法结束后务必清理实例、关闭Driver:

import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;

public class TestClass1 {
    @Test
    public void testCase1() {
        Utilities utilities = SingletonDesignPattern.getInstance();
        // 执行测试操作,比如打开目标页面
        utilities.getDriver().get("https://example.com");
        // ...其他测试步骤
    }

    @AfterMethod
    public void tearDown() {
        Utilities utilities = SingletonDesignPattern.getInstance();
        if (utilities.getDriver() != null) {
            // 关闭当前线程的Driver
            utilities.getDriver().quit();
            // 清理ThreadLocal中的实例,释放资源
            SingletonDesignPattern.cleanInstance();
        }
    }
}

测试框架的并行配置(以TestNG为例)

最后要确保测试框架配置了正确的并行策略,比如在testng.xml中这样设置:

<suite name="TestSuite" parallel="classes" thread-count="2">
    <test name="TestGroup">
        <classes>
            <class name="com.yourpackage.TestClass1"/>
            <class name="com.yourpackage.TestClass2"/>
        </classes>
    </test>
</suite>

这里parallel="classes"表示按测试类并行执行,thread-count="2"设置线程数为2,你也可以根据需求改成parallel="tests"或parallel="methods"。

关键注意事项

  • 测试结束后必须调用cleanInstance()并关闭Driver,否则ThreadLocal中的实例会一直占用内存,引发资源泄漏。
  • 确保Utilities类的Driver初始化逻辑是独立的,比如在Utilities构造方法中执行new ChromeDriver(),保证每个实例对应一个全新的Driver。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:09:01