Selenium 2.0 WebDriver 使用指南

SeleniumWebDriver
注意:咱们正致力于完善帮助指南的每个章节,虽然这个章节仍然存在须要完善的地方,不过咱们坚信当前你看到的帮助信息是精确无误的,后续咱们会提供更多的指导信息来完善帮助文档。
1.WebDriver介绍
Selenium2.0最主要的新特性就是集成了WebDriverAPI。咱们设计WebDriver的初衷是提供更加简单明了的接口来弥补Selenium-RCAPI的不足。在动态网页中,一般只会更新局部的html元素,WebDriver会很好的帮助用户快速定位这些元素。咱们最终的目的是经过提供精心设计的面向对象API来解决现代高级网页中的测试难题。
2.WebDriver如何驱动浏览器?与Selenium-RC有什么区别?
不一样类型的浏览器都会有原生的接口支持自动化操做,Selenium经过这些接口直接向浏览器发送指令。如何发送这些指令取决于你当前使用的浏览器类型,咱们将在这一章节后面来详细介绍。
看上去WebDriver与以前Selenium-RC的实现方式相似,实际上二者之间存在着本质的区别。对于全部类型的浏览器Selenium-RC都是使用的同一种方法:当浏览器启动时,向其中注入javascript,从而使用这些js来驱动浏览器中的AUT(ApplicationUnderTest)。WebDriver并无使用这种技术,它是经过调用浏览器原生的自动化API直接驱动浏览器。
3.WebDriver与SeleniumServer
是否须要是用SeleniumServer取决于你使用WebDriver的方式。如下两种状况不须要使用SeleniumServer,WebDriver直接运行浏览器便可:一、testcases仅仅使用了Webdriver的API;二、浏览器和testcase在同一台PC上,并且testcases仅仅使用了Webdriver的API。
如下三种状况你须要结合SeleniumServer来使用WebDriver:
1)使用Selenium-Grid管理集群环境(或者虚拟机)上的testcase;
2)须要调用非本机上的不一样版本的浏览器;
3)未使用任何languagebinding(java/c#/python/ruby),且有意向使用HtmlUnitDriver。
4.配置Selenium-WebDriver工程
安装Selenium是指在开发环境上配置一个工程,而后能够在这个工程中用Selenium编写程序。如何配置取决于你使用的开发语言和编程环境。
使用Maven是配置一个Selenium2.0java工程最简单的方式。Maven会下载全部javabingdings以及全部相关的库(theSelenium2.0javaclientlibrary)。经过使用pom.xml(maven配置文件)来新建工程,你能够根据本身的喜爱将Maven工程导入IntelliJIDEA或者Eclipse。
首先,建立一个文件夹存放Maven工程文件。而后,建立pom.xml,你可使用texteditor来编辑。鉴于已经有不少关于“如何在Maven工程中使用pom.xml”优秀的参考文献,这里将再也不过多的讨论相关细节。下面给出一个示例,为你的工程也建立一个相似的文件。
<?xmlversion="1.0"encoding="UTF-8"?>
<projectxmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>MySel20Proj</groupId>
<artifactId>MySel20Proj</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.38.0</version>
</dependency>
<dependency>
<groupId>com.opera</groupId>
<artifactId>operadriver</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.opera</groupId>
<artifactId>operadriver</artifactId>
<version>1.5</version>
<exclusions>
<exclusion>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-remote-driver</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
</project>javascript

  请确认你使用的WebDriver是最新的当前版本。在这篇文档撰写时,上述示例给出的是最新的版本。在Selenium2.0发布不久WebDriver就有过频繁的更新。请在这个连接MavenDownloadPage确认当前的版本,相应地修改你工程中的pon.xml。
   如今,你能够经过dos界面使用CD命令进入工程所在文件夹,经过如下命令运行Maven。
   mvncleaninstall
   运行以后会自动下载Selenium及相关套件,并加载到你的工程中去。
   最后,将你的工程导入到你偏好的IDE中。若是你对导入的过程不是很清楚,咱们已经准备了操做指南。
   ImportingamavenprojectintoIntelliJIDEA.ImportingamavenprojectintoEclipse
   5.如何将自动化工程从Selenium1.0迁移到Selenium2.0
   已经在Selenium1.0上构建测试工程的用户,咱们为您提供了一份指导如何将已有的代码迁移到Selenium2.0。Selenium2.0的首席开发工程师SimonStewart为此撰写了一片文章:MagratingFromSeleniumRCtoSeleniumWebDriver。
   6.Selenium-WebDriverAPI简介
   WebDriver能够用来实现Web应用程序的自动化测试,特别适合于验证明际结果是否符合预期结果的场景。WebDriver旨在提供比Selenium1.0更加易用、友好的API,便于用户的探索和理解,从而使测试用例变得容易阅读和维护。WebDriver没有使用任何第三方测试框架,因此它能够很好与单元测试工具或者最古老的main函数结合使用。本章节将介绍如何使用WebDriver的API,帮助你慢慢开始了解WebDriver。若是你尚未新建一个Selenium工程,请先完成这个操做,在这个章节的上面有详细的描述。
   当你建立完Selenium工程后,你会发现WebDriver和普通的第三方库同样是彻底独立的,在你使用以前不须要启动任何额外的进程或者安装程序,相反若是你使用Selenium-RC须要先启动代理服务器。
   注意:当你使用以下WebDriver时须要额外的步骤:ChromeDriver,OperaDriver,AndroidDriver,IPhoneDriver。
   如今你确定跃跃欲试要写一些代码了。咱们以一个简单的例子来开始第一段旅程:在Google上搜索“Cheese”,并打印出搜索结果网页的标题。
packageorg.openqa.selenium.example;
importorg.openqa.selenium.By;
importorg.openqa.selenium.WebDriver;
importorg.openqa.selenium.WebElement;
importorg.openqa.selenium.firefox.FirefoxDriver;
importorg.openqa.selenium.support.ui.ExpectedCondition;
importorg.openqa.selenium.support.ui.WebDriverWait;
publicclassSelenium2Example{
publicstaticvoidmain(String[]args){
//建立一个FirefoxDriver实例
//这个类依赖于接口而不是接口的实现
WebDriverdriver=newFirefoxDriver();
//使用get方法访问Google
driver.get("http://www.google.com");
//使用下面这个方法也可以达到访问Google的目的
//driver.navigate().to("http://www.google.com");
//找到html输入框的name
WebElementelement=driver.findElement(By.name("q"));
//输入要查找的内容
element.sendKeys("Cheese!");
//提交表单,WebDriver会自动找到咱们须要提交的元素所在的表单
element.submit();
//打印网页的标题
System.out.println("Pagetitleis:"+driver.getTitle());
//Google的搜索网页会经过JS动态渲染
//等待页面加载完毕,超时时间为10秒
(newWebDriverWait(driver,10)).until(newExpectedCondition<Boolean>(){
publicBooleanapply(WebDriverd){
returnd.getTitle().toLowerCase().startsWith("cheese!");
}
});
//控制台上将打印以下信息:"cheese!-GoogleSearch"
System.out.println("Pagetitleis:"+driver.getTitle());
//关闭浏览器
driver.quit();
}
}
   在本章节的接下来篇幅,咱们将学习如何使用WebDriver操做你的浏览器,如何使用框架和窗口来测试Web网站。固然,咱们将提供更加翔实的论述和举例。
   7.Selenium-WebDriverAPI详解
   7.1获取Web页面
   咱们第一件要作的事是经过WebDriver取得Web页面的控制权,通常状况下使用get方法
   driver.get("http://www.google.com");
   在某些状况下,好比操做系统和浏览器的穿插组合,WebDriver有可能不会等待Web页面加载完成,这种状况下WebDriver会返回错误或者直接运行下一步操做。为了保证程序的健壮性,你须要等待页面中某个元素加载完成后再进行下一步操做,请参考ExplicitandImplicitWaits。
   7.2定位UI元素
   咱们能够经过WebDriver实例或者WebElement类来定位UI元素。咱们为每种编程语言都提供了两种方法:“FindElement”和“FindElements”。第一种方法返回的一个WebElement,找不到则抛出异常。第二个方法返回一个WebElement链表(List),在找不到任何DOM元素的状况下会返回空的链表。
   Find方法会使用相似探测器的类,类名叫作By。下面列举By的一些经常使用方法:
   ByID
   当咱们定位一个UI元素,这个是最有效也是最好的方法。不过这个方法不是万能的,有的前端开发在设计UI元素时会遗漏ID或者使用动态ID,这两种状况下都要避免使用这个方法。这时候使用获取class名称方法比ByID更合适。
   示例:如何使用该方法定位元素
   <divid="coolestWidgetEvah">...</div>
   WebElementelement=driver.findElement(By.id("coolestWidgetEvah"));css

  ByClassName
   在这种场景下,咱们引用DOM元素的属性。实际状况是不少元素都有同样的ClassName,所以找到多个有相同ClassName的元素,比找到第一个拥有这个ClassName的元素来的更重要。
   示例:如何使用该方法定位元素
   <divclass="cheese"><span>Cheddar</span></div><divclass="cheese"><span>Gouda</span></div>
   List<WebElement>cheeses=driver.findElements(By.className("cheese"));
   ByTagName
   DOM元素Tag的名称。
   示例:如何使用该方法定位元素
   <iframesrc="..."></iframe>
   WebElementframe=driver.findElement(By.tagName("iframe"));
   ByName
   找到与Name属性相同的Input元素。
   示例:如何使用该方法定位元素
   <inputname="cheese"type="text"/>
   WebElementcheese=driver.findElement(By.name("cheese"));
   ByLinkText
   找到与Text属性精确匹配的超连接。
   示例:如何使用该方法定位元素
   <ahref="http://www.google.com/search?q=cheese">cheese</a>
   WebElementcheese=driver.findElement(By.linkText("cheese"));
   ByPartialLinkText
   找到与Text属性模糊匹配的超连接。
   示例:如何使用该方法定位元素
   <ahref="http://www.google.com/search?q=cheese">searchforcheese</a>
   WebElementcheese=driver.findElement(By.partialLinkText("cheese"));
   ByCSS
   这个方法名称意味着它是一个CSS探测器。前提是浏览器默认支持这种方法,建议根据W3C的标准文档构建CSS选择器。若是浏览器不支持CSS选择器,可使用Sizzle。IE6,7和FireFox3.0就是使用Sizzle做为CSS查询引擎。
   注意不是全部浏览器都使用一样的CSS选择器表达式,有些CSS可能只在某一个版本中生效。
   示例:如何使用该方法定位元素
   <divid="food"><spanclass="dairy">milk</span><spanclass="dairyaged">cheese</span></div>
   WebElementcheese=driver.findElement(By.cssSelector("#foodspan.dairy.aged"));
   ByXPath
   当有须要时,WebDriver还可使用浏览器自带的XPATH。对于那些不支持XPATH的浏览器,咱们提供了WebDriver特有的实现方式。请确保熟悉XPATH在不一样的引擎中的区别,不然会致使一些不可预料的问题。
   Driver大小写敏感属性值是否可见是否支持XAPTH
   HtmlUnitDriver仅识别小写可见是
   IEDriver仅识别小写可见否
   FireFoxDiver大小写不敏感可见是上面的表格有一些抽象,让咱们来看个例子
   <inputtype="text"name="example"/>
   <INPUTtype="text"name="other"/>
   List<WebElement>inputs=driver.findElements(By.xpath("//input"));
   匹配结果以下
   XPATH表达式HtmlUnitDriverFireFoxDriverIEDriver
   //input122
   //INPUT020有些标签的属性有默认值,这种状况下不指定属性值则匹配默认值。好比,"input"标签"type"属性默认为"text"。使用XPATH的首要原则就是不要忽略这些隐藏的实现。
   使用JavaScript
   只要返回的是一个WebElement,你还可使用任意的JS代码查找Web元素,根据查询结果会自动修改成一个WebElement对象。
   一个简单的使用jQuery的例子:
   WebElementelement=(WebElement)((JavascriptExecutor)driver).executeScript("return$('.cheese')[0]");
   查找页面中每一个label的全部Input元素:
List<WebElement>labels=driver.findElements(By.tagName("label"));
List<WebElement>inputs=(List<WebElement>)((JavascriptExecutor)driver).executeScript(
"varlabels=arguments[0],inputs=[];for(vari=0;i<labels.length;i++){"+
"inputs.push(document.getElementById(labels[i].getAttribute('for')));}returninputs;",labels);
   7.3模拟用户输入行为
   咱们已经演示了在文本框输入文本内容,其余Web元素应该如何操做呢?你能够触发CheckBox的某个选项,也能够选择Select的某个选项。WebDriver处理Select元素也很简单。
WebElementselect=driver.findElement(By.tagName("select"));
List<WebElement>allOptions=select.findElements(By.tagName("option"));
for(WebElementoption:allOptions){
System.out.println(String.format("Valueis:%s",option.getAttribute("value")));
option.click();
}
   上面的例子,将选择Web页面中的第一个Select元素,并将循环打印出选项的取值并单击选项。或许你已经注意到,使用这个方法并非最有效的。WebDriver提供一个“Select”类,这个类的方法更适合于处理上述这种场景。
Selectselect=newSelect(driver.findElement(By.tagName("select")));
select.deselectAll();
select.selectByVisibleText("Edam");
   上面的例子,首先去除选定第一个选项的焦点,而后选中取值为"Edam"的选项。
   一旦你完成了全部表单字段的输入,下一步就是提交表单。一种方法就是找到Web页面中的Submit按钮并单击:
   driver.findElement(By.id("submit")).click();
   做为另外一种选择,WebDriver的Element类有一个更加便利的方法"sublmit"。若是你对表单中的某个Element使用该方法,WebDriver将会走读其所在的DOM对象,直到找到其所属的表单,并提交。若是该Element并不在某个表单中,将会抛出异常NoSuchElementException。
   element.submit();
   7.4在windows和frames间切换
   有些Web程序包含许多Frame和窗口,WebDriver提供"switchto"方法在这之间进行切换:
   driver.switchTo().window("windowName");
   全部传输给WebDriver的指定将被传输给切换后的窗口。如何直到窗口的名称呢?查看JS并打开该窗口就能够了:
   <ahref="somewhere.html"target="windowName">Clickheretoopenanewwindow</a>
   做为另外一种选择,你可使用一个“窗口句柄”传递给"switchTo().window()"方法。根据此方法,将会使用迭代器遍历全部打开的窗口:
   for(Stringhandle:driver.getWindowHandles()){
   driver.switchTo().window(handle);
   }
   你也能够在Frame之间切换(或者进入Frame):
   driver.switchTo().frame("frameName");
   你还能够根据路径使用Frame的子Frame,并且能够经过索引定位Frame。
   driver.switchTo().frame("frameName.0.child");
   以上方法将切换到名称为“frameName”的Frame的第一个子Frame,全部Frame都是Web页面的最顶端开始计数。
   7.5弹出框
   Selenium2.0beta1版本,咱们提供方法获取弹出框。在你触发弹出框的操做后,你能够用一下方法进入弹出框:
   Alertalert=driver.switchTo().alert();
   以上方法将会返回当前当前打开的alert对象,你能够对这个对象进行任何可操做:点击取消,点击肯定,关闭窗口,获取alert的文本内容等。这个接口在alerts、confirms、prompts对象上都有很好的应用,具体请参见API文档。
   7.6Navigation:浏览器本地历史记录
   前文中,咱们使用get方法来获取网页(driver.get("http://www.example.com"))。正如你看到的,WebDriver有很多轻量级的功能聚焦的接口,Navigation就是这样一个。正由于加载网页是一个再普通不过的需求,这个方法存在于Driver类下面,可是用法很简单:
   driver.navigate().to("http://www.example.com");
   重申一下,"navigate().to()"和"get()"作的是一样的事情,只不过其中一个更适合打印。
   Navigate接口还提供方法能够在浏览器历史记录中先后翻页。
   driver.navigate().forward();
   driver.navigate().back();
   请注意,以上功能彻底取决于底层的浏览器。若是你习惯跨浏览器操做,当你使用这些接口时可能会出现意想不到的的异常。html

  7.7Cookies
   在咱们开始下一步的讲解以前,你可能对WebDriver如何操做本地Cookies很感兴趣。首先,你必须处于当前Cookie的做用域。若是你在打开一个网页以前尝试预置Cookie,并且你的主页大到须要很长一段时间来加载,这时候你须要找一个小点的网页来替代,好比HTTP404网页(http://example.com/some404page)。
//打开Cookie做用的网站
driver.get("http://www.example.com");
//设置全局Cookie
Cookiecookie=newCookie("key","value");
driver.manage().addCookie(cookie);
//输出当前网页全部可用的Cookie
Set<Cookie>allCookies=driver.manage().getCookies();
for(CookieloadedCookie:allCookies){
System.out.println(String.format("%s->%s",loadedCookie.getName(),loadedCookie.getValue()));
}
//你又三种方法删除Cookie
//Byname
driver.manage().deleteCookieNamed("CookieName");
//ByCookie
driver.manage().deleteCookie(loadedCookie);
//Orallofthem
driver.manage().deleteAllCookies();
?? 7.8修改用户代理服务器
?? 对于FireFox来讲很简单:
FirefoxProfileprofile=newFirefoxProfile();
profile.addAdditionalPreference("general.useragent.override","someUAstring");
WebDriverdriver=newFirefoxDriver(profile);
   7.9拖拽Web元素
   下面是一个拖拽Web页面元素的例子,前提是本地事件必须可用。
   WebElementelement=driver.findElement(By.name("source"));
   WebElementtarget=driver.findElement(By.name("target"));
   (newActions(driver)).dragAndDrop(element,target).perform();
   8各类Driver的特性以及如何选择合适Driver
   翻译中
   9向前兼容:融合WebDriver和Selenium-RC
   翻译中
   10为远程WebDriver单独启动SeleniumServer
   翻译中
   译者注:
   一、原文连接:http://www.seleniumhq.org/docs/03_webdriver.jsp。
   二、文中只包含了java相关的操做,WebDriver还支持c#/Python/Ruby/Perl/PHP/Perl,若有须要,请阅读原文。
   三、languagebinding,又叫gluecode,意思是胶水代码,好比有个C++的lib库,java调用这个库的api就叫javabinding。参考:http://en.wikipedia.org/wiki/Language_binding。
   四、措辞拙劣,有些单词句子没有深究就直译了,深感从阅读到翻译差的不只仅是一本字典,还有文化的差别。笔者强烈推荐直接阅读官网上的原文,若是个人译文给你形成误解,深感不安。这也是最后三章不敢继续班门弄斧的缘由,等我对Selenium熟悉了以后再回来补全。前端

本文选自:http://www.spasvo.com/ceshi/open/kygncsgj/Selenium/2014214135011.htmljava

 

相关文章
相关标签/搜索