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

使用Selenium Grid与JUnit5,如何从指定节点重启失败的长测试?

从特定节点重新执行长耗时Selenium测试的解决方案

针对用Selenium Grid+JUnit5运行超长时间测试(30分钟),因定位器小问题失败后需从头执行的痛点,以下是几种可行方案:

1. 拆分测试步骤+状态快照

将长测试拆分为多个独立的业务步骤,每个步骤完成后保存当前Selenium会话的关键状态(Cookie、LocalStorage、当前页面URL、已完成的业务上下文)。通过系统参数指定从某一步骤开始执行,跳过前置步骤并直接加载对应状态。

示例代码思路:

@TestTemplate
void executeLongTestSteps(TestInfo testInfo) {
    int currentStep = extractStepNumber(testInfo.getDisplayName());
    int startStep = Integer.getInteger("startFromStep", 1);

    if (currentStep < startStep) {
        return;
    }

    // 若为起始步骤,加载前置状态
    if (currentStep == startStep && startStep > 1) {
        loadSessionState(driver, "step-" + (startStep - 1) + ".state");
    }

    // 执行当前步骤逻辑
    switch(currentStep) {
        case 1:
            // 初始化流程:登录、进入目标页面
            saveSessionState(driver, "step-1.state");
            break;
        case 2:
            // 执行表单填写步骤
            saveSessionState(driver, "step-2.state");
            break;
        // 后续步骤依次实现
    }
}

// 自定义方法:保存会话状态到本地文件
private void saveSessionState(WebDriver driver, String filePath) {
    Map<String, Object> state = new HashMap<>();
    state.put("cookies", driver.manage().getCookies());
    state.put("url", driver.getCurrentUrl());
    // 序列化state到文件
}

// 自定义方法:从文件加载会话状态
private void loadSessionState(WebDriver driver, String filePath) {
    Map<String, Object> state = /* 从文件反序列化 */;
    driver.get((String) state.get("url"));
    Set<Cookie> cookies = (Set<Cookie>) state.get("cookies");
    cookies.forEach(cookie -> driver.manage().addCookie(cookie));
    driver.navigate().refresh();
}

2. Selenium Grid会话复用

启动Grid节点时添加--session-reuse true参数,允许测试会话在失败后保留。修复定位器后,通过已有的sessionId重新连接到Grid上的存活会话,直接从失败节点继续执行。

示例代码:

// 测试失败时,打印sessionId到控制台
System.out.println("Current session ID: " + ((RemoteWebDriver) driver).getSessionId());

// 修复后,用该sessionId重新连接
DesiredCapabilities caps = new DesiredCapabilities();
// 设置和原测试一致的capabilities
RemoteWebDriver driver = new RemoteWebDriver(new URL("http://grid-host:4444/wd/hub"), caps);
driver.setSessionId("your-existing-session-id");

// 直接执行失败节点的逻辑
driver.findElement(By.id("fixed-locator")).click();

3. 拆分独立测试类+标签执行

将长测试拆分为多个独立JUnit测试类,用@Order控制执行顺序,@Tag标记业务节点。失败后,直接运行对应标签的测试,同时在测试类中加载前置状态,跳过已完成的流程。

示例结构:

@Order(1)
@Tag("user-login")
class UserLoginTest {
    @Test
    void loginAndSaveState() {
        // 登录逻辑,保存状态到文件
        saveSessionState(driver, "login.state");
    }
}

@Order(2)
@Tag("order-submit")
class OrderSubmitTest {
    @BeforeEach
    void loadLoginState() {
        // 加载登录状态,跳过登录步骤
        loadSessionState(driver, "login.state");
    }

    @Test
    void submitOrder() {
        // 执行订单提交逻辑
    }
}

若order-submit步骤失败,修复后直接运行该标签的测试:

mvn test -Dgroups=order-submit

4. 自定义JUnit5扩展实现断点续跑

编写JUnit5扩展,实现BeforeTestExecutionCallback和AfterTestExecutionCallback接口,在每个测试方法执行前后自动保存/加载状态。通过系统参数resumeFromTest指定从某个测试方法开始执行,跳过前置方法。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 22:10:50