自动化测试析疑——WebDriver启动时白屏挂起问题解决方法

简介:

WebDriver启动的时候很容易无限挂起,直到外围框架设定的超时时间达到而退出运行,给测试运行带来很大的困扰。而实际上WebDriver有一组timeout的设置方法,启动时的挂起属于页面加载的范畴,所以可以考虑用timeouts().pageLoadTimeout()来重新启动一个有效的实例来执行测试。

  Java代码:

* Description: catch page load timeout Exception and restart a new session.
* 内容描述:通过页面跳转是否超时来测试WebDriver启动时是否发生挂死异常。
*
* @param driver RemoteWebDriver object.
* @param browser the browser mode.
* @param testUrl the url used to navigate by the driver.get method.
* @throws Exception
*/
private boolean hasLoadPageSucceeded(RemoteWebDriver driver, String browser, String testUrl) throws Exception {
try {
driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);
driver.get(testUrl);
return true;
} catch (TimeoutException te) {
LOG.error("******************本次启动WebDriver异常挂起******************");
setBuildEnvChoice(browser);
driverObjectInitalize();
return false;
}
}
/**
* Description: catch page load timeout Exception and restart a new session.
* 内容描述:循环一定次数测试WebDriver启动是否挂死。
*
* @param driver RemoteWebDriver object.
* @param browser the browser mode.
* @param testUrl the url used to navigate by the driver.get method.
* @param repeatTimes retry times.
* @throws Exception
*/
private void driverStatusTest(RemoteWebDriver driver, String browser, String testUrl, int repeatTimes) throws Exception {
int index = 0;
boolean suspended = true;
while (index < repeatTimes && suspended){
suspended = !hasLoadPageSucceeded(driver, browser, testUrl);
index ++;
}
if (index == repeatTimes && suspended){
throw new RuntimeException("can not start webdriver successfully, it's suspended!");
}
}
/**
* Description: start webdirver after capability settings completed.
* 内容描述:在做好配置之后创建WebDriver实例。
*
* @throws Exception
*/
private String driverObjectInitalize() throws Exception{
if (USE_DRIVERSERVER){//是否使用IEDirverServer
driver = new RemoteWebDriver(service.getUrl(), capability);
return service.getUrl().toString();
}else{
URL url = new URL("http://localhost:" + server.getPort() + "/wd/hub");
driver = new RemoteWebDriver(url, capability);
return "http://localhost:" + server.getPort() + "/wd/hub";
}
}
/**
* Description: start webdirver
* 内容描述:启动WebDriver实例。
*
* @param browser the browser mode
* @throws RuntimeException
*/
protected void startWebDriver(String browser) {
try {
setBrowserMode(browser);
String url = driverObjectInitalize();//about:blank is useless on some machines.
driverStatusTest(driver, browser, url, 2);
driver.manage().timeouts().implicitlyWait(maxWaitfor, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(maxWaitfor, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(maxLoadTime, TimeUnit.SECONDS);
} catch (Exception e) {
LOG.error(e);
throw new RuntimeException(e);
}
}
/**
* Description: set browser mode on local machines: do not close browsers already opened.
* 内容描述:选择在本机执行,有人工干预,无需杀掉浏览器进程。
*
* @throws Exception
*/
private void setBrowserMode(String browser) throws Exception{
if (browser.toLowerCase().contains("ie") || browser.toLowerCase().contains("internetexplorer")) {
capability = DesiredCapabilities.internetExplorer();
} else if (browser.toLowerCase().contains("ff") || browser.toLowerCase().contains("firefox")) {
capability = DesiredCapabilities.firefox();
} else if (browser.toLowerCase().contains("chrome")) {
capability = DesiredCapabilities.chrome();
} else if (browser.toLowerCase().contains("safari")) {
capability = DesiredCapabilities.safari();
} else if (browser.toLowerCase().contains("opera")) {
capability = DesiredCapabilities.opera();
} else if (browser.toLowerCase().contains("htmlunit")) {
capability = DesiredCapabilities.htmlUnit();
} else {
throw new IllegalArgumentException("you are using wrong mode of browser paltform!");
}
}

上面的文档给出的解决方案只是能够部分地解决工具问题,但有时候这种hang死会发生在timeouts().pageLoadTimeout()发生作用之前。也就是说,这需要更为彻底的方法去解决这个问题,我想到最简单的方式是用独立的守护线程去看守,具体代码如下:

[html] view plaincopyprint?private final int DRIVER_STATUS_TEST_TIMES = 2;
private final int DRIVER_START_TIMEOUT = 30000;
/**
* Description: start webdirver
* 内容描述:启动WebDriver实例。
*
* @param browserMode the browser mode
*/
private void startWebDriver(String browserMode){
try {
setBuildEnvChoice(browserMode);
initalizeWebDriver(DRIVER_START_TIMEOUT);
//the address "about:blank" is sometimes useless.
ensureWebDriverStatus(browserMode, getServerAddress(), DRIVER_STATUS_TEST_TIMES);
setPageLoadTimeout(maxLoadTime);
setElementLocateTimeout(maxWaitfor);
setScriptingTimeout(maxWaitfor);
actionDriver = new Actions(driver);
ASSERT = new StarNewAssertion(driver, LOG_ABS, className, logger, devidor);
pass("webdriver new instance created");
} catch (Exception e) {
LOG.error(e);
throw new RuntimeException(e);
}
}
/**
* Description: start webdirver using browser iexplore
* 内容描述:默认选择IE模式创建WebDriver实例。
*/
protected void startWebDriver() {
startWebDriver("ie");
}
/**
* Description: start webdirver after capabilities settings completed.
* 内容描述:在做好配置之后创建WebDriver实例。
*/
private void initalizeWebDriver() {
WebDriverListener listener = new WebDriverListener(LOG_ABS, className, logger, devidor);
if (USE_DRIVERSERVER) {// 是否使用IEDirverServer
driver = new EventFiringWebDriver(new RemoteWebDriver(service.getUrl(), capabilities)).register(listener);
} else {
try {
URL url = new URL("http://localhost:" + server.getPort() + "/wd/hub");
driver = new EventFiringWebDriver(new RemoteWebDriver(url, capabilities)).register(listener);
} catch (MalformedURLException e) {
throw new RuntimeException("illegal url!");
}
}
}
/**
* Description: start and see if webdirver start successfully.
* 内容描述:创建并且判断WebDriver实例是否启动成功。
*
* @param timeout timeout for start webdriver.
* @param redoCount retry times for start webdriver.
* @throws Exception
*/
private void initalizeWebDriver(long timeout, int redoCount) throws Exception {
for (int i = 0; i < redoCount; i++) {
Thread thread_start = new Thread(new Runnable() {
public void run() {// 用一个独立的线程启动WebDriver
initalizeWebDriver();
}
});
thread_start.start();
waitFor(thread_start, timeout);//为启动WebDriver设定超时时间
if (!thread_start.isAlive()) {
return;
} else {
thread_start.interrupt();
consoleError("start Webdriver failed 【" + i + "】 times!");
}
if (thread_start.isAlive() && i == redoCount){// 如果最终没能启动成功则抛出错误
thread_start.interrupt();
throw new RuntimeException("can not start webdriver, check your platform configurations!");
}
}
}

最新内容请见作者的GitHub页:http://qaseven.github.io/

目录
相关文章
|
1月前
|
Web App开发 JavaScript 测试技术
python自动化测试实战 —— WebDriver API的使用
python自动化测试实战 —— WebDriver API的使用
33 1
|
1月前
|
Java 测试技术 持续交付
深入理解与应用Selenium WebDriver进行自动化测试
【4月更文挑战第25天】 在现代软件开发过程中,自动化测试已成为确保产品质量和加速市场发布的关键步骤。Selenium WebDriver作为业界广泛采用的自动化测试工具之一,提供了一种灵活且高效的方式来模拟用户与Web应用程序交互。本文将探讨Selenium WebDriver的核心概念、架构以及实际应用中的技巧和最佳实践。通过深入分析其工作原理及常见问题解决方案,旨在帮助测试工程师提升测试效率,确保测试结果的准确性和可靠性。
21 1
|
1月前
|
Java 测试技术 定位技术
《手把手教你》系列技巧篇(二十三)-java+ selenium自动化测试-webdriver处理浏览器多窗口切换下卷(详细教程)
【4月更文挑战第15天】本文介绍了如何使用Selenium进行浏览器窗口切换以操作不同页面元素。首先,获取浏览器窗口句柄有两种方法:获取所有窗口句柄的集合和获取当前窗口句柄。然后,通过`switchTo().window()`方法切换到目标窗口句柄。在项目实战部分,给出了一个示例,展示了在百度首页、新闻页面和地图页面之间切换并输入文字的操作。最后,文章还探讨了在某些情况下可能出现的问题,并提供了一个简单的本地HTML页面示例来演示窗口切换的正确操作。
72 0
|
10月前
|
前端开发
前端项目实战拾壹-pda测试平板打包为何白屏
前端项目实战拾壹-pda测试平板打包为何白屏
89 0
|
9月前
|
Web App开发 JavaScript 前端开发
自动化兼容性检查和解决方案:应用不会再白屏了(二)
自动化兼容性检查和解决方案:应用不会再白屏了
66 0
|
9月前
|
Web App开发 前端开发 JavaScript
自动化兼容性检查和解决方案:应用不会再白屏了(一)
自动化兼容性检查和解决方案:应用不会再白屏了
79 0
|
Web App开发 数据采集 缓存
曲鸟全栈UI自动化教学(四):Selenium工作原理及Webdriver对浏览器的配置和操作
曲鸟全栈UI自动化教学(四):Selenium工作原理及Webdriver对浏览器的配置和操作
424 0
曲鸟全栈UI自动化教学(四):Selenium工作原理及Webdriver对浏览器的配置和操作
|
缓存 前端开发 JavaScript
使用 webdriver API 编写自动化脚本的基本语法
1. 打开和关闭浏览器 1)打开浏览器并访问 URL 2)关闭浏览器窗口 2. 元素的定位 1)以 id 定位元素 2)以 name 定位元素 3)以 tag name 定位元素 4)以 class name 定位元素 5)以 xpath 定位元素 6)以 css selector 定位元素 7)以 link text 定位元素 8)以 partial link text 定位元素 3. 操作测试元素 1)键盘输入与鼠标点击 2)submit 提交表单 3)获取元素内容 4. 添加等待 1)sleep 休眠 2)智能等待 5. 打印网页 title 和 URL 6. 浏览器操作 1)设置浏览器
148 0
|
存储 编解码 JSON
基于Unittest框架,使用Python+Selenium+Webdriver的WebUI自动化测试项目应用实例(附源码)
基于Unittest框架,使用Python+Selenium+Webdriver的WebUI自动化测试项目应用实例(附源码)
232 0
基于Unittest框架,使用Python+Selenium+Webdriver的WebUI自动化测试项目应用实例(附源码)
|
JSON 测试技术 数据格式
软件测试面试题:请描述Selenium Webdriver的工作原理。
软件测试面试题:请描述Selenium Webdriver的工作原理。
114 0