自動化測試析疑——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!"); } } } |
posted on 2013-04-09 10:42 順其自然EVO 閱讀(1391) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄 、管理方向