TestNG无法运行并行测试 仅单个Chrome实例执行用例
问题根因
你把WebDriver driver定义成了测试类的成员变量,TestNG配置parallel="methods"执行时,会在同一个测试类实例下开多个线程并发执行所有@Test方法,多个线程会同时读写这同一个driver变量:
- 第一个线程执行
setUp()初始化driver打开第一个浏览器,还没等跑测试步骤,第二个线程执行setUp()就会把driver的引用覆盖成新打开的第二个浏览器实例 - 之前的线程找不到自己一开始绑定的浏览器,后续的导航、元素操作全都会落到最后一次赋值的driver对应的浏览器上,最终就出现开了好几个Chrome窗口,只有一个在跑用例,剩下的全停在初始空白
data;页的现象。
修复方案
方案1:ThreadLocal绑定线程独立driver(推荐)
用ThreadLocal给每个执行线程单独存一份独立的driver实例,从根源上避免多线程共享变量冲突,修改后的测试类代码如下:
public class Tests { // 为每个线程维护独立的driver实例,互不干扰 private ThreadLocal<WebDriver> driver = new ThreadLocal<>(); private static String OptionalProductQuantity = "6"; private static String ChatMessage = "Hi"; ChromeOptions options = new ChromeOptions().setBinary("C:\\Program Files\\Google\\Chrome Beta\\Application\\chrome.exe"); @BeforeTest public void oneTimeSetUp() { System.setProperty("webdriver.chrome.driver", ".\\Drivers\\chromedriver.exe"); } @BeforeMethod public void setUp() { // 当前线程初始化自己的driver,存入ThreadLocal driver.set(new ChromeDriver(options)); } @Test(description = "Adding product to the cart") public void AddtoCart() { // 取出当前线程绑定的driver使用 Commons common = new Commons(driver.get()); common.navigateTo(Constants.TRUCKX_URL); common.clickElement(AddtoCart.Checkout); } @Test(description = "Validating the homepage's UI is fine ") public void ValidateHomepageUI() { Commons common = new Commons(driver.get()); common.navigateTo(Constants.TRUCKX_URL); } @AfterMethod public void exitBrowser() { // 关闭当前线程对应的浏览器,移除引用避免内存泄漏 driver.get().quit(); driver.remove(); } }
改完直接跑就行,不需要调整现有TestNG XML配置,每个线程打开的浏览器都会独立执行自己的测试步骤。
方案2:调整TestNG并行策略
如果不想改动现有代码逻辑,可以把XML里的并行模式从parallel="methods"改成parallel="classes",再把每个@Test方法拆到单独的测试类里,TestNG会给每个测试类创建独立实例,每个实例持有自己的driver,不会出现引用覆盖的问题。但这种方式需要拆分测试类,后续维护成本高,优先选ThreadLocal方案。
补充说明
你当前XML里没配置thread-count参数,TestNG会根据CPU核心数、待执行方法数默认计算启动线程数,你看到启动3个浏览器就是默认线程数计算的结果,不需要额外调整。后续写并行用例时,所有和单线程绑定的资源(比如driver、测试上下文参数)都不要定义为类共享变量,统一用ThreadLocal存储即可。
内容的提问来源于stack exchange,提问作者Chauhan Ankit
相关产品推荐
相关产品推荐

