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

Java Cucumber Selenium场景中如何同时处理双浏览器双用户操作

解决Cucumber Selenium+PicoContainer同场景双浏览器并行问题

你的核心问题是PicoContainer默认采用单例注入,导致同一个场景内多次获取WebDriver时复用了同一个实例,无法同时启动两个独立浏览器。下面是具体的改造方案:

1. 自定义浏览器管理类

创建一个BrowserManager类,用于维护多个独立的WebDriver实例,按用户标识区分:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.HashMap;
import java.util.Map;

public class BrowserManager {
    private final Map<String, WebDriver> driverMap = new HashMap<>();

    public WebDriver getDriver(String userIdentifier) {
        if (!driverMap.containsKey(userIdentifier)) {
            // 初始化Chrome浏览器实例,可按需添加配置(如无头模式、窗口大小等)
            WebDriver driver = new ChromeDriver();
            driver.manage().window().maximize();
            driverMap.put(userIdentifier, driver);
        }
        return driverMap.get(userIdentifier);
    }

    // 关闭所有浏览器实例,用于场景结束后清理
    public void closeAllDrivers() {
        driverMap.values().forEach(driver -> {
            if (driver != null) {
                driver.quit();
            }
        });
        driverMap.clear();
    }
}

2. 调整Step Definitions的注入方式

将原来直接注入WebDriver改为注入BrowserManager,在步骤中根据用户标识获取对应Driver:

import io.cucumber.java.After;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

public class TableLockSteps {
    private final BrowserManager browserManager;
    private WebDriver user1Driver;
    private WebDriver user2Driver;

    // 通过PicoContainer注入BrowserManager(默认单例,确保同一场景内共享)
    public TableLockSteps(BrowserManager browserManager) {
        this.browserManager = browserManager;
        this.user1Driver = browserManager.getDriver("user1");
        this.user2Driver = browserManager.getDriver("user2");
    }

    @Given("User1用Access1账号在Chrome浏览器登录并打开某张表")
    public void user1_login_and_open_table() {
        user1Driver.get("你的登录页面URL");
        // 执行Access1账号登录操作
        // 打开目标表的操作
    }

    @When("User2用Access2账号在另一Chrome浏览器登录,打开同一张表")
    public void user2_login_and_open_same_table() {
        user2Driver.get("你的登录页面URL");
        // 执行Access2账号登录操作
        // 打开目标表的操作
    }

    @Then("应看到错误提示“the table is locked by user 1”")
    public void verify_lock_error_message() {
        WebDriverWait wait = new WebDriverWait(user2Driver, Duration.ofSeconds(10));
        wait.until(ExpectedConditions.visibilityOfElementLocated(/* 错误提示元素定位器 */));
        // 验证错误文本匹配
    }

    @When("User1登出后,User2再次打开该表")
    public void user1_logout_and_user2_reopen_table() {
        // User1执行登出操作
        user1Driver.get("登出页面URL");
        // User2刷新或重新打开目标表页面
        user2Driver.navigate().refresh();
    }

    @Then("User2可编辑该表,最后User2登出")
    public void verify_table_editable_and_user2_logout() {
        // 验证表可编辑(如检查编辑按钮状态)
        // User2执行登出操作
        user2Driver.get("登出页面URL");
    }

    // 场景结束后清理所有浏览器进程
    @After
    public void tearDown() {
        browserManager.closeAllDrivers();
    }
}

3. 关键注意事项

  • PicoContainer会自动维护BrowserManager的单例生命周期,确保同一场景内所有步骤共享同一个实例,从而管理两个独立的Driver。
  • 如果框架有自定义Driver配置(如ChromeOptions、代理),可在BrowserManager.getDriver()方法中统一添加,保证实例配置一致。
  • 必须在@After钩子中关闭所有Driver,避免浏览器进程残留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 14:21:31