使用WebDriver遇到的那些坑

在作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

相关文章
相关标签/搜索