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!"); } } } |