基于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
相关产品推荐
相关产品推荐

