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

Selenium Java UI自动化测试时Chrome浏览器重复打开的问题解决

Selenium+Java UI自动化测试:重复打开浏览器问题的解决方法

问题场景

运行SubmitOrderTest类的submitOrder方法时,会打开两个Chrome浏览器,而非预期的一个。

涉及代码

  1. SubmitOrderTest类(继承DefaultTest):
public class SubmitOrderTest extends DefaultTest {
    @Test
    public void submitOrder()
    {
        LandingPage landingPage = launchWebsite();
        landingPage.login("standard_user", "secret_sauce");
        String errorMessage = landingPage.getErrorMessage();
    }
}
  1. DefaultTest类:
public class DefaultTest {
    public WebDriver driver;
    public LandingPage landingPage;

    public WebDriver initializeDriver() 
    {
        driver=new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
        driver.manage().window().maximize();
        return driver;
    }

    @BeforeMethod(alwaysRun=true)
    public LandingPage launchWebsite() 
    {
        driver = initializeDriver();
        landingPage = new LandingPage(driver);
        landingPage.goTo();
        return landingPage;
    }

    @AfterMethod(alwaysRun=true)
    public void tearDown()
    {
        driver.close();
    }
}
  1. LandingPage类(继承AbstractComponents):
public class LandingPage extends AbstractComponents {
    WebDriver driver;
    public LandingPage(WebDriver driver) 
    {
        super(driver);
        this.driver=driver;
        PageFactory.initElements(driver, this);
    }

    @FindBy(id = "user-name")
    WebElement userName;
    @FindBy(id = "password")
    WebElement userPassword;
    @FindBy(id ="login-button")
    WebElement loginButton;
    @FindBy(xpath = "//h3[@data-test='error']")
    WebElement errorMessage;

    public void goTo()
    {
        driver.get("https://www.saucedemo.com/");
    }

    public void login(String email, String password)
    {
        userName.sendKeys(email);
        userPassword.sendKeys(password);
        loginButton.click();
    }

    public String getErrorMessage()
    {
        waitForElementToAppear(errorMessage);
        return errorMessage.getText();
    }
}

预期与实际流程

  • 预期:打开一个浏览器→执行登录→关闭浏览器
  • 实际:打开浏览器1→打开浏览器2→在浏览器2执行登录→仅关闭浏览器2

问题根源

DefaultTest类中被@BeforeMethod注解标记的launchWebsite方法,会在每个@Test方法执行前自动调用一次,而submitOrder方法里又手动调用了launchWebsite(),导致两次执行initializeDriver(),初始化了两个WebDriver实例,对应打开两个浏览器。


修改方案

1. 修改SubmitOrderTest类

去掉测试方法中手动调用launchWebsite()的代码,直接使用父类在@BeforeMethod中已经初始化好的landingPage实例:

public class SubmitOrderTest extends DefaultTest {
    @Test
    public void submitOrder()
    {
        landingPage.login("standard_user", "secret_sauce");
        String errorMessage = landingPage.getErrorMessage();
    }
}

2. 优化DefaultTest类(可选)

由于父类已经持有landingPage实例,可将launchWebsite的返回值改为void,避免误调用:

public class DefaultTest {
    public WebDriver driver;
    public LandingPage landingPage;

    public WebDriver initializeDriver() 
    {
        driver=new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
        driver.manage().window().maximize();
        return driver;
    }

    @BeforeMethod(alwaysRun=true)
    public void launchWebsite() // 修改返回值为void
    {
        driver = initializeDriver();
        landingPage = new LandingPage(driver);
        landingPage.goTo();
    }

    @AfterMethod(alwaysRun=true)
    public void tearDown()
    {
        driver.close();
    }
}

修改后执行流程

  1. @BeforeMethod自动执行launchWebsite,打开一个Chrome浏览器并初始化landingPage
  2. @Test方法使用已初始化的landingPage完成登录操作
  3. @AfterMethod执行tearDown关闭浏览器

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:58:16