在作web項目的自動化端到端測試時主要使用的是Selenium?WebDriver來驅動瀏覽器。Selenium WebDriver的優勢是支持的語言多,支持的瀏覽器多。主流的瀏覽器Chrome、Firefox、IE等都支持,手機上的瀏覽器Android、IPhone等也支持,甚至還支持PhantomJS(因爲PhantomJS跑測試時並不須要渲染元素,因此執行速度快)。
使用WebDriver遇到的那些坑
webdriver實用乾貨
可是我在使用Selenium WebDriver時,遇到了不少坑。這些問題,有的是由於Selenium WebDriver與瀏覽器不一樣版本之間兼容性的問題,有的是Selenium WebDriver自己的bug,固然也不乏本身對Selenium WebDriver某些功能理解不透徹。我花時間總結了一下,分享給你們,但願你們之後遇到問題能夠避過這些坑,少走彎路。另外也總結了一些使用WebDriver的比較好的實踐,也一併分享給你們。
WebDriver每次啓動一個Firefox的實例時,會生成一個匿名的profile,並不會使用當前Firefox的profile。這點必定要注意。好比若是訪問被測試的web服務須要經過代理,你想直接設置Firefox的代理是行不通的,由於WebDriver啓動的Firefox實例並不會使用你這個profile,正確的作法是經過FirefoxProfile來設置。
public WebDriver create(){
FirefoxProfile firefoxProfile=new FirefoxProfile();
firefoxProfile.setPreference("network.proxy.type",1);
firefoxProfile.setPreference("network.proxy.http",yourProxy);
firefoxProfile.setPreference("network.proxy.http_port",yourPort);
firefoxProfile.setPreference("network.proxy.no_proxies_on","");
return new FirefoxDriver(firefoxProfile);
}
經過FirefoProfile也能夠設置Firefox其它各類配置。若是要默認給Firefox安裝插件的話,能夠將插件放置到Firefox安裝目錄下的默認的plugin文件夾中,這樣即便是使用一個全新的profile也能夠應用此plugin。
使用WebDriver點擊界面上Button元素時,若是當前Button元素被界面上其餘元素遮住了,或沒出如今界面中(好比Button在頁面底部,可是屏幕只能顯示頁面上半部分),使用默認的WebElement.Click()可能會觸發不了Click事件。
修正方案是找到該頁面元素後直接發送一條Click的JavaScript指令。
((JavascriptExecutor)webDriver).executeScript("arguments[0].click();",webElement);
當進行了一些操做發生頁面跳轉時,最好加一個Wait方法等待page load完成再進行後續操做。方法是在某個時間段內判斷document.readyState是否是complete。
protected Function<WebDriver,Boolean>isPageLoaded(){
return new Function<WebDriver,Boolean>(){
@Override
public Boolean apply(WebDriver driver){
return((JavascriptExecutor)driver).executeScript("return?????????????????????????????????????????????????????? document.readyState").equals("complete");
}
};
}
public void waitForPageLoad(){
WebDriverWait wait=new WebDriverWait(webDriver,30);
wait.until(isPageLoaded());
}
若是頁面有Ajax操做,須要寫一個Wait方法等待Ajax操做完成。方式與上一條中的基本相同。好比一個Ajax操做是用於向DropDownList中填充數據,則寫一個方法判斷該DropDownList中元素是否多餘0個。
private Function<WebDriver,Boolean>haveMoreThanOneOption(final By element){
return new Function<WebDriver,Boolean>(){
@Override
public Boolean apply(WebDriver driver){
WebElement webElement=driver.findElement(element);
if(webElement==null){
return false;
}else{
int size=webElement.findElements(By.tagName("option")).size();
return size>=1;
}
}
};
}
public void waitForDropDownListLoaded(){
WebDriverWait wait=new WebDriverWait(webDriver,30);
wait.until(isPageLoaded());
}
以此類推,咱們能夠判斷某個元素是否呈現、某個class是否append成功等一系列方法來判斷ajax是否執行完成。
若是網站使用了JQuery的動畫效果,咱們在運行測試的時候其實能夠disable JQuery的animation,一方面能夠加快測試的速度,另外一方面能夠增強測試的穩定性(若是啓用了Animation,使用WebDriver驅動瀏覽器時可能會出現一些沒法預料的異常)。
((JavascriptExecutor)driver).executeScript("jQuery.fx.off=true");
因爲WebDriver要驅動瀏覽器,因此測試運行的時間比較長,咱們能夠並行跑測試以節省時間。若是你使用的是maven構建工具,能夠配置surefire plugin時,在configruation節點加入如下配置。(網易Dagger框架支持的作法)
<parallel>classes</parallel>
<threadCount>3</threadCount>
<perCoreThreadCount>false</perCoreThreadCount>
當測試fail的時候,若是當前使用的WebDriver實現了TakesScreenshot接口,咱們就能夠調用相應的方法截下當前瀏覽器呈現的web頁面,這樣有利於快速定位出錯的緣由。
public void getScreenShot(){
if(webDriver instanceof TakesScreenshot){
TakesScreenshot screenshotTaker=(TakesScreenshot)webDriver;
File file=screenshotTaker.getScreenshotAs(savePath);
}
}
若是頁面彈出了瀏覽器自帶的警告框(使用JavaScript的Alert方法),Selenium WebDriver在點選次警告框時會偶發性失敗。具體緣由還未查明。解決方案是儘可能不使用Alert方法的警告框,而是本身實現模式窗口(好比Jquery UI的模式窗口)來實現警告框效果。這樣即保證了測試的穩定性,另外咱們本身能夠控制警告框的樣式,給用戶帶來更好的體驗。
常常更新Selenium的版本。注意常常上Selenium的官網看是否發佈了新的版本,新的版本都修復了那些bug,若是包含你遇到的bug,就能夠升級到目前的版本。html
本文選自:http://www.spasvo.com/ceshi/open/kygncsgj/Selenium/2014128170115.htmlweb