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

基于WinAppDriver的Java Selenium自动化运行一段时间后失效

解决WinAppDriver长期运行卡顿及操作超时重试问题

一、实现操作超时抛出异常,触发RetryAnalyzer重试

隐式等待仅对findElement/findElements的元素查找过程生效,无法控制点击、输入等交互操作的超时。要实现操作超时抛异常,需手动封装超时控制逻辑,结合TestNG的IRetryAnalyzer触发重试:

1. 封装超时执行工具类

用Java的ExecutorService实现任务的超时控制,超时直接抛出TimeoutException:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class TimeoutUtils {
    public static void executeWithTimeout(Runnable task, long timeout, TimeUnit timeUnit) throws TimeoutException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        try {
            executor.submit(task).get(timeout, timeUnit);
        } catch (TimeoutException e) {
            throw e; // 抛出超时异常,供RetryAnalyzer捕获
        } catch (Exception e) {
            throw new RuntimeException("操作执行失败", e);
        } finally {
            executor.shutdownNow();
        }
    }
}

2. 自定义RetryAnalyzer捕获超时异常

让重试逻辑仅在超时异常发生时触发:

import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
import java.util.concurrent.TimeoutException;

public class WinAppRetryAnalyzer implements IRetryAnalyzer {
    private int retryCount = 0;
    private static final int MAX_RETRY_TIMES = 3;

    @Override
    public boolean retry(ITestResult result) {
        // 仅当异常为TimeoutException时重试,且不超过最大次数
        if (retryCount < MAX_RETRY_TIMES && result.getThrowable() instanceof TimeoutException) {
            retryCount++;
            return true;
        }
        return false;
    }
}

3. 在测试用例中使用

将交互操作放入超时控制逻辑中,并指定重试分析器:

import org.testng.annotations.Test;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@Test(retryAnalyzer = WinAppRetryAnalyzer.class)
public void testClickOperation() throws TimeoutException {
    // 查找元素(隐式等待会控制这个步骤的超时)
    WebElement targetBtn = driver.findElement(By.id("submitBtn"));
    // 控制点击操作超时2秒
    TimeoutUtils.executeWithTimeout(targetBtn::click, 2, TimeUnit.SECONDS);
}

二、解决WinAppDriver长期运行卡顿问题

WinAppDriver长时间运行后卡顿,通常是内存泄漏或会话残留导致,可通过以下方式缓解:

  • 定期重启WinAppDriver服务:
    不要长期复用同一个driver实例,运行一定数量的测试用例后,关闭当前driver,强制杀掉WinAppDriver进程,再重新启动服务并创建新driver。示例代码:

    public static void restartWinAppDriver() throws IOException {
        // 关闭当前driver
        if (driver != null) {
            driver.quit();
        }
        // 杀掉WinAppDriver进程
        Runtime.getRuntime().exec("taskkill /F /IM WinAppDriver.exe");
        // 等待1秒后重新启动WinAppDriver(根据实际路径调整)
        Runtime.getRuntime().exec("C:\\Program Files (x86)\\Windows Application Driver\\WinAppDriver.exe");
        // 重新初始化driver
        driver = new WindowsDriver(new URL("http://127.0.0.1:4723"), desiredCapabilities);
    }
    

    可以结合TestNG的@AfterMethod或定时任务,每执行N个用例后调用一次该方法。

  • 清理测试残留资源:
    每个测试用例结束后,显式关闭应用窗口、清空会话,避免无用资源占用:

    @AfterMethod
    public void tearDown() {
        if (driver != null) {
            // 关闭所有应用窗口
            for (String handle : driver.getWindowHandles()) {
                driver.switchTo().window(handle);
                driver.close();
            }
            driver.quit();
        }
    }
    
  • 监控系统资源:
    7*24小时运行需关注Windows系统的内存、CPU占用,必要时在测试间隙添加短暂休眠,或通过脚本定期释放系统缓存。

  • 升级WinAppDriver版本:
    旧版本的WinAppDriver存在已知的内存泄漏bug,升级到最新稳定版可解决部分卡顿问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:15:23