TestNG执行Selenium并行测试异常,顺序执行正常且账号仅传单个浏览器
问题根因
- 测试类成员变量
driver线程不安全:多线程并行执行@BeforeMethod时,不同线程的驱动实例会互相覆盖该变量的引用,最终只有最后赋值的实例能正常执行后续登录操作,其余线程的driver指向错误实例。 - TestNG套件缺少并行配置:当前的testng.xml未配置
parallel和thread-count参数,默认以单线程模式执行,即便驱动层做了ThreadLocal处理也不会真正并行运行,若手动在启动参数加了并行规则也会因上述变量问题出现异常。 - Firefox驱动初始化代码不完整:
WebDriverManager.firefoxdriver()后缺少.setup()调用,会导致火狐浏览器启动失败。 - 缺少测试后资源清理逻辑:未在
@AfterMethod中销毁对应线程的驱动实例并清空ThreadLocal存储,线程复用会导致实例串用。
修复方案
1. 修改测试类驱动调用逻辑
不要用类成员变量存储驱动实例,所有场景直接调用静态getDriver()方法获取当前线程对应的驱动,避免多线程覆盖:
@BeforeMethod public void setUp() { // 配置文件仅加载一次即可,可移至@BeforeSuite提升执行效率 if(prop == null){ basePage = new BasePage(); prop = basePage.init_proprties(); } String browser = prop.getProperty("browser"); // 无需用变量接收,init_driver已将实例存入当前线程的ThreadLocal basePage.init_driver(browser); loginPage = new LoginPage(getDriver()); getDriver().get(prop.getProperty("url")); homePage = loginPage.doLogin(prop.getProperty("username"), prop.getProperty("password")); } // 新增测试结束清理逻辑 @AfterMethod public void tearDown(){ getDriver().quit(); // 清空当前线程存储的驱动实例,避免内存泄漏和线程复用串用 tldriver.remove(); }
2. 完善TestNG并行配置
在suite根标签新增并行规则和线程数配置,以下是按测试方法并行、最大2个线程的示例:
<suite name="CRM Test Suite" parallel="methods" thread-count="2"> <listeners> <listener class-name="com.qa.zoho.listeners.ExtentReportListener" /> <!-- <listener class-name="com.qa.zoho.listeners.TestAllureListener" /> --> </listeners> <test name="CRM Sanity Test"> <classes> <class name="com.qa.zoho.tests.HomePageTest" /> </classes> </test> </suite>
如果需要按测试类/测试标签并行,将parallel属性值改为classes/tests即可
3. 修复Firefox驱动初始化代码
补全火狐驱动的初始化调用:
else if (browserName.equals("ff")) { WebDriverManager.firefoxdriver().setup(); tldriver.set(new FirefoxDriver()); }
4. 补充校验点
确认LoginPage类的doLogin方法内部操作均使用构造方法传入的驱动实例,没有调用静态驱动变量,避免实例串用。
内容的提问来源于stack exchange,提问作者Niks
相关产品推荐
相关产品推荐

