开发者社区> 玄学酱> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

自动化测试析疑——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/

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
xttdriver.pl
!/usr/bin/perl $Header: rdbms/demo/rman_xttconvert/xttdriver.pl /main/10 2015/05/18 06:18:23 asathyam Exp $ xttdriver.
1462 0
Linux环境下使用图形化界面的SVN客户端软件-RabbitVCS
如果想在Linux环境下使用图形化界面的SVN客户端软件,那么RabbitVCS绝对是首选,可以媲美Windows环境下用的TortoiseSVN,甚至连操作都基本一样,所以强烈推荐给各位童鞋。 RabbitVCS基本支持所有的Linux发行版本包括Ubuntu、Debian、Fedora、Arch Linux、Gentoo、Mandriva、OpenSUSE、RHEL、CentOS 5等。
1943 0
解剖SQLSERVER 第十一篇 对SQLSERVER的多个版本进行自动化测试(译)
原文:解剖SQLSERVER 第十一篇 对SQLSERVER的多个版本进行自动化测试(译) 解剖SQLSERVER 第十一篇    对SQLSERVER的多个版本进行自动化测试(译) http://improve.dk/automated-testing-of-orcamdf-against-multiple-sql-server-versions/ 自从我发布了OrcaMDF Studio,我已经意识到SQL2005和SQL2008之间的一些系统表的差异。
1119 0
Android 测试 Intel HAXM 超快模拟器时出现的问题解决
Android 测试 Intel HAXM 超快模拟器时出现的问题解决 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循“署名-非商业用途-保持一致”创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。
1047 0
使用WebDriver遇到的那些坑
在做web项目的自动化端到端测试时主要使用的是Selenium WebDriver来驱动浏览器。Selenium WebDriver的优点是支持的语言多,支持的浏览器多。主流的浏览器Chrome、Firefox、IE等都支持,手机上的浏览器Android、IPhone等也支持,甚至还支持PhantomJS(由于PhantomJS跑测试时并不需要渲染元素,所以执行速度快)。
920 0
+关注
玄学酱
这个时候,玄酱是不是应该说点什么...
20683
文章
438
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载