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

Selenium测试运行时ChromeDriver多次启动致用例失败问题排查

问题根因

你遇到的Chrome重复启动、测试崩溃问题,核心是代码完全没有做WebDriver实例的复用控制,每触发一次实例创建逻辑就会拉起一个全新的Chrome进程,最终耗尽系统资源导致失败,具体错误点如下:

  • LauchDriver类的LauDriver()方法没有单例校验,每次被调用都会执行new ChromeDriver()创建新的浏览器进程,没有任何复用已有实例的逻辑。
  • ContactpageObjects类的无参构造方法中,每次实例化页面对象都会主动新建LauchDriver并调用LauDriver()创建新驱动,没有设计为接收外部传入的已有WebDriver实例。
  • 测试类中存在大量无意义的重复实例创建逻辑:
    • enterSearchText方法中首先手动调用LauDriver()启动第一个Chrome打开目标网址
    • 随后调用getObjects()时,方法内部newContactpageObjects会触发构造器逻辑启动第二个Chrome
    • 之后手动newContactpageObjects会启动第三个Chrome
    • 最后调用getObjects().getSubmit()时会启动第四个Chrome
    • 仅这一个测试方法就会拉起4个独立Chrome进程,后续运行contactHeader测试方法时还会继续创建新的浏览器实例。
  • 全链路没有任何浏览器退出、资源释放的逻辑,运行结束的Chrome进程会持续驻留后台占用内存、端口资源。
修复方案

1. 重构驱动管理类,实现单例复用

将WebDriver改为全局唯一实例,仅在第一次调用时初始化,同时新增统一的资源释放方法:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import io.github.bonigarcia.wdm.WebDriverManager;
import java.time.Duration;

public class LaunchDriver {
    private static WebDriver driver;

    public static WebDriver getDriver() {
        if (driver == null) {
            WebDriverManager.chromedriver().setup();
            driver = new ChromeDriver();
            // 可在此处统一配置全局浏览器参数
            driver.manage().window().maximize();
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        }
        return driver;
    }

    public static void quitDriver() {
        if (driver != null) {
            driver.quit();
            driver = null;
        }
    }
}

2. 重构页面对象类,依赖注入驱动实例

移除页面对象构造器中自行创建驱动的逻辑,改为接收外部传入的已有WebDriver实例:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import java.util.List;

public class ContactpageObjects {
    private WebDriver driver;

    public ContactpageObjects(WebDriver driver){
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }
    
    @FindBy(css = ".hero")
    List<WebElement> header1 ;
    
    @FindBy(xpath = "//input[@class = 'search__input'][@data-highlight = 'true']")
    WebElement searchField;
    
    @FindBy(xpath = ".//button[@class = 'search__submit']")
    WebElement submit;
    
    
    public List<WebElement> getHeader(){
        return header1;
    }
    
    public WebElement getSearchField(){
        return searchField;
    }
    public WebElement getSubmit(){
        return submit;
    }
}

3. 重构测试类,统一管理驱动生命周期

移除测试方法中重复创建驱动、重复实例化页面对象的逻辑,通过测试生命周期注解统一初始化和销毁资源:

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class ContactPageTest {
    private WebDriver driver;
    private ContactpageObjects pageObj;

    @BeforeEach
    public void setUp() {
        // 每个用例运行前获取唯一驱动实例,初始化页面对象
        driver = LaunchDriver.getDriver();
        pageObj = new ContactpageObjects(driver);
    }
 
    @Test
    public void enterSearchText(){
        driver.get("https://www.mywebsite.uk/speed");
        for(WebElement a: pageObj.getHeader()){
            String text = a.findElement(By.cssSelector(".hero__title")).getText();
            assertEquals("Contact", text);
            System.out.println(text);
        }
        pageObj.getSearchField().sendKeys("closing");
        pageObj.getSubmit().click(); 
    }

     @Test
    public void contactHeader() {
        driver.get("https://www.mywebsite.uk/speed");
        for(WebElement a:pageObj.getHeader()){
            String text = a.findElement(By.cssSelector(".hero__title")).getText();
            assertEquals("Contact", text);
            System.out.println(text);
        }
    }

    @AfterAll
    public static void tearDown() {
        // 所有用例运行完成后统一退出浏览器释放资源
        LaunchDriver.quitDriver();
    }
}

补充说明:如果需要用例之间完全隔离(避免上一个用例的操作状态影响下一个),可以将驱动初始化和退出逻辑分别放到@BeforeEach和@AfterEach中,保证每个用例启动全新的独立浏览器,但同一个用例运行过程中绝对不能重复创建多个WebDriver实例。

内容的提问来源于stack exchange,提问作者e-Tester

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:06:07