【譯】Selenium 2.0 WebDriver

Selenium WebDriver

 
注意:咱們正致力於完善幫助指南的每個章節,雖然這個章節仍然存在須要完善的地方,不過咱們堅信當前你看到的幫助信息是精確無誤的,後續咱們會提供更多的指導信息來完善幫助文檔。
 
 

1.WebDriver介紹

Selenium 2.0最主要的新特性就是集成了WebDriver API。咱們設計WebDriver的初衷是提供更加簡單明瞭的接口來彌補Selenium-RC API的不足。在動態網頁中,一般只會更新局部的html元素,WebDriver會很好的幫助用戶快速定位這些元素。咱們最終的目的是經過提供精心設計的面向對象API來解決現代高級網頁中的測試難題。javascript

2.WebDriver如何驅動瀏覽器?與Selenium-RC有什麼區別?

不一樣類型的瀏覽器都會有原生的接口支持自動化操做,Selenium經過這些接口直接向瀏覽器發送指令。如何發送這些指令取決於你當前使用的瀏覽器類型,咱們將在這一章節後面來詳細介紹。css

看上去WebDriver與以前Selenium-RC的實現方式相似,實際上二者之間存在着本質的區別。對於全部類型的瀏覽器Selenium-RC都是使用的同一種方法:當瀏覽器啓動時,向其中注入javascript,從而使用這些js來驅動瀏覽器中的AUT(Application Under Test)。WebDriver並無使用這種技術,它是經過調用瀏覽器原生的自動化API直接驅動瀏覽器。html

3.WebDriver與Selenium Server

是否須要是用Selenium Server取決於你使用WebDriver的方式。如下兩種狀況不須要使用Selenium Server,WebDriver直接運行瀏覽器便可:一、testcases僅僅使用了Webdriver的API;二、瀏覽器和testcase在同一臺PC上,並且testcases僅僅使用了Webdriver的API。前端

如下三種狀況你須要結合Selenium Server來使用WebDriver:java

1)使用Selenium-Grid管理集羣環境(或者虛擬機)上的testcase;python

2)須要調用非本機上的不一樣版本的瀏覽器;web

3)未使用任何language binding(java/c#/python/ruby),且有意向使用HtmlUnitDriver。apache

4.配置Selenium-WebDriver工程

安裝Selenium是指在開發環境上配置一個工程,而後能夠在這個工程中用Selenium編寫程序。如何配置取決於你使用的開發語言和編程環境。
 
使用Maven是配置一個Selenium 2.0 java工程最簡單的方式。Maven會下載全部java bingdings以及全部相關的庫(the Selenium 2.0 java client library)。經過使用pom.xml(maven配置文件)來新建工程,你能夠根據本身的喜愛將Maven工程導入IntelliJ IDEA或者Eclipse。

首先,建立一個文件夾存放Maven工程文件。而後,建立pom.xml,你可使用text editor來編輯。鑑於已經有不少關於「如何在Maven工程中使用pom.xml」優秀的參考文獻,這裏將再也不過多的討論相關細節。下面給出一個示例,爲你的工程也建立一個相似的文件。
 
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="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.0 http://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>
請確認你使用的WebDriver是最新的當前版本。在這篇文檔撰寫時,上述示例給出的是最新的版本。在Selenium2.0發佈不久WebDriver就有過頻繁的更新。請在這個連接 Maven Download Page確認當前的版本,相應地修改你工程中的pon.xml。

如今,你能夠經過dos界面使用CD命令進入工程所在文件夾,經過如下命令運行Maven。編程

 

mvn clean install

 

運行以後會自動下載Selenium及相關套件,並加載到你的工程中去。c#

最後,將你的工程導入到你偏好的IDE中。若是你對導入的過程不是很清楚,咱們已經準備了操做指南。

Importing a maven project into IntelliJ IDEA.Importing a maven project into Eclipse

5.如何將自動化工程從Selenium1.0遷移到Selenium2.0

已經在Selenium1.0上構建測試工程的用戶,咱們爲您提供了一份指導如何將已有的代碼遷移到Selenium2.0。Selenium2.0的首席開發工程師Simon Stewart爲此撰寫了一片文章:Magrating From Selenium RC to Selenium WebDriver

6.Selenium-WebDriver API簡介

WebDriver能夠用來實現Web應用程序的自動化測試,特別適合於驗證明際結果是否符合預期結果的場景。WebDriver旨在提供比Selenium1.0更加易用、友好的API,便於用戶的探索和理解,從而使測試用例變得容易閱讀和維護。WebDriver沒有使用任何第三方測試框架,因此它能夠很好與單元測試工具或者最古老的main函數結合使用。本章節將介紹如何使用WebDriver的API,幫助你慢慢開始瞭解WebDriver。若是你尚未新建一個Selenium工程,請先完成這個操做,在這個章節的上面有詳細的描述。
 
當你建立完Selenium工程後,你會發現WebDriver和普通的第三方庫同樣是徹底獨立的,在你使用以前不須要啓動任何額外的進程或者安裝程序,相反若是你使用Selenium-RC須要先啓動代理服務器。
 
注意:當你使用以下WebDriver時須要額外的步驟:Chrome Driver,Opera Driver,Android Driver,IPhone Driver。
 

如今你確定躍躍欲試要寫一些代碼了。咱們以一個簡單的例子來開始第一段旅程:在Google上搜索「Cheese」,並打印出搜索結果網頁的標題。

 

package org.openqa.selenium.example;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

public class Selenium2Example  {
    public static void main(String[] args) {
        // 建立一個FirefoxDriver實例
        // 這個類依賴於接口而不是接口的實現
        WebDriver driver = new FirefoxDriver();

        // 使用get方法訪問Google
        driver.get("http://www.google.com");
        // 使用下面這個方法也可以達到訪問Google的目的
        // driver.navigate().to("http://www.google.com");

        // 找到html輸入框的name
        WebElement element = driver.findElement(By.name("q"));

        // 輸入要查找的內容
        element.sendKeys("Cheese!");

        // 提交表單,WebDriver會自動找到咱們須要提交的元素所在的表單
        element.submit();

        // 打印網頁的標題
        System.out.println("Page title is: " + driver.getTitle());
        
        // Google的搜索網頁會經過JS動態渲染
        // 等待頁面加載完畢,超時時間爲10秒
        (new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver d) {
                return d.getTitle().toLowerCase().startsWith("cheese!");
            }
        });

        // 控制檯上將打印以下信息: "cheese! - Google Search"
        System.out.println("Page title is: " + driver.getTitle());
        
        // 關閉瀏覽器
        driver.quit();
    }
}

在本章節的接下來篇幅,咱們將學習如何使用WebDriver操做你的瀏覽器,如何使用框架和窗口來測試Web網站。固然,咱們將提供更加翔實的論述和舉例。

 

7.Selenium-WebDriver API詳解

7.1獲取Web頁面

咱們第一件要作的事是經過WebDriver取得Web頁面的控制權,通常狀況下使用get方法
driver.get("http://www.google.com");
在某些狀況下,好比操做系統和瀏覽器的穿插組合,WebDriver有可能不會等待Web頁面加載完成,這種狀況下WebDriver會返回錯誤或者直接運行下一步操做。爲了保證程序的健壯性,你須要等待頁面中某個元素加載完成後再進行下一步操做,請參考 Explicit and Implicit Waits
 

7.2定位UI元素

咱們能夠經過WebDriver實例或者WebElement類來定位UI元素。咱們爲每種編程語言都提供了兩種方法:「Find Element」和「Find Elements」。第一種方法返回的一個WebElement,找不到則拋出異常。第二個方法返回一個WebElement鏈表(List),在找不到任何DOM元素的狀況下會返回空的鏈表。
Find方法會使用相似探測器的類,類名叫作By。下面列舉By的一些經常使用方法:
 
By ID
當咱們定位一個UI 元素,這個是最有效也是最好的方法。不過這個方法不是萬能的,有的前端開發在設計UI元素時會遺漏ID或者使用動態ID,這兩種狀況下都要避免使用這個方法。這時候使用獲取class名稱方法比By ID更合適。
示例:如何使用該方法定位元素
<div id="coolestWidgetEvah">...</div>
WebElement element = driver.findElement(By.id("coolestWidgetEvah"));

 

By Class Name

在這種場景下,咱們引用DOM元素的屬性。實際狀況是不少元素都有同樣的Class Name,所以找到多個有相同Class Name的元素,比找到第一個擁有這個Class Name的元素來的更重要。

示例:如何使用該方法定位元素

 

<div class="cheese"><span>Cheddar</span></div><div class="cheese"><span>Gouda</span></div>
List<WebElement> cheeses = driver.findElements(By.className("cheese"));

By Tag Name

 

DOM元素Tag的名稱。

示例:如何使用該方法定位元素

 

<iframe src="..."></iframe>
WebElement frame = driver.findElement(By.tagName("iframe"));

By Name

 

找到與Name屬性相同的Input元素。

示例:如何使用該方法定位元素

 

<input name="cheese" type="text"/>
WebElement cheese = driver.findElement(By.name("cheese"));

By Link Text

 

找到與Text屬性精確匹配的超連接。

示例:如何使用該方法定位元素

 

<a href="http://www.google.com/search?q=cheese">cheese</a>
WebElement cheese = driver.findElement(By.linkText("cheese"));

By Partial Link Text

 

找到與Text屬性模糊匹配的超連接。

示例:如何使用該方法定位元素
<a href="http://www.google.com/search?q=cheese">search for cheese</a>
WebElement cheese = driver.findElement(By.partialLinkText("cheese"));

By CSS
這個方法名稱意味着它是一個CSS探測器。前提是瀏覽器默認支持這種方法,建議根據 W3C的標準文檔構建CSS選擇器。若是瀏覽器不支持CSS選擇器,可使用 Sizzle。IE6,7和FireFox3.0就是使用Sizzle做爲CSS查詢引擎。
 
注意不是全部瀏覽器都使用一樣的CSS選擇器表達式,有些CSS可能只在某一個版本中生效。

示例:如何使用該方法定位元素

 

<div id="food"><span class="dairy">milk</span><span class="dairy aged">cheese</span></div>
WebElement cheese = driver.findElement(By.cssSelector("#food span.dairy.aged"));


By XPath

當有須要時,WebDriver還可使用瀏覽器自帶的XPATH。對於那些不支持XPATH的瀏覽器,咱們提供了WebDriver特有的實現方式。請確保熟悉XPATH在不一樣的引擎中的區別,不然會致使一些不可預料的問題。

Driver 大小寫敏感 屬性值是否可見 是否支持XAPTH
HtmlUnit Driver 僅識別小寫 可見
IE Driver 僅識別小寫 可見
FireFox Diver 大小寫不敏感 可見

上面的表格有一些抽象,讓咱們來看個例子

 

<input type="text" name="example" />
<INPUT type="text" name="other" />

List<WebElement> inputs = driver.findElements(By.xpath("//input"));


匹配結果以下

 

XPATH表達式 HtmlUnit Driver FireFox Driver IE Driver
//input 1 2 2
//INPUT 0 2 0

有些標籤的屬性有默認值,這種狀況下不指定屬性值則匹配默認值。好比,"input"標籤"type"屬性默認爲"text"。使用XPATH的首要原則就是不要忽略這些隱藏的實現。

使用JavaScript

只要返回的是一個Web Element,你還可使用任意的JS代碼查找Web元素,根據查詢結果會自動修改成一個WebElement對象。

一個簡單的使用jQuery的例子:

 

WebElement element = (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(
    "var labels = arguments[0], inputs = []; for (var i=0; i < labels.length; i++){" +
    "inputs.push(document.getElementById(labels[i].getAttribute('for'))); } return inputs;", labels);

 

 

7.3模擬用戶輸入行爲

咱們已經演示了在文本框輸入文本內容,其餘Web元素應該如何操做呢?你能夠觸發CheckBox的某個選項,也能夠選擇Select的某個選項。WebDriver處理Select元素也很簡單。
WebElement select = driver.findElement(By.tagName("select"));
List<WebElement> allOptions = select.findElements(By.tagName("option"));
for (WebElement option : allOptions) {
    System.out.println(String.format("Value is: %s", option.getAttribute("value")));
    option.click();
}

上面的例子,將選擇Web頁面中的第一個Select元素,並將循環打印出選項的取值並單擊選項。或許你已經注意到,使用這個方法並非最有效的。WebDriver提供一個「Select」類,這個類的方法更適合於處理上述這種場景。
Select select = new Select(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提供"switch to"方法在這之間進行切換:
driver.switchTo().window("windowName");

全部傳輸給WebDriver的指定將被傳輸給切換後的窗口。如何直到窗口的名稱呢?查看JS並打開該窗口就能夠了:
<a href="somewhere.html" target="windowName">Click here to open a new window</a>

做爲另外一種選擇,你可使用一個「窗口句柄」傳遞給"switchTo().window()"方法。根據此方法,將會使用迭代器遍歷全部打開的窗口:
for (String handle : 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.0 beta1版本,咱們提供方法獲取彈出框。在你觸發彈出框的操做後,你能夠用一下方法進入彈出框:
Alert alert = 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();


請注意,以上功能徹底取決於底層的瀏覽器。若是你習慣跨瀏覽器操做,當你使用這些接口時可能會出現意想不到的的異常。

 

 

7.7Cookies

 
在咱們開始下一步的講解以前,你可能對WebDriver如何操做本地Cookies很感興趣。首先,你必須處於當前Cookie的做用域。若是你在打開一個網頁以前嘗試預置Cookie,並且你的主頁大到須要很長一段時間來加載,這時候你須要找一個小點的網頁來替代,好比HTTP 404網頁( http://example.com/some404page)。
// 打開Cookie做用的網站
driver.get("http://www.example.com");

// 設置全局Cookie
Cookie cookie = new Cookie("key", "value");
driver.manage().addCookie(cookie);

// 輸出當前網頁全部可用的Cookie
Set<Cookie> allCookies = driver.manage().getCookies();
for (Cookie loadedCookie : allCookies) {
    System.out.println(String.format("%s -> %s", loadedCookie.getName(), loadedCookie.getValue()));
}

// 你又三種方法刪除Cookie
// By name
driver.manage().deleteCookieNamed("CookieName");
// By Cookie
driver.manage().deleteCookie(loadedCookie);
// Or all of them
driver.manage().deleteAllCookies();

7.8 修改用戶代理服務器

 
對於FireFox來講很簡單:
FirefoxProfile profile = new FirefoxProfile();
profile.addAdditionalPreference("general.useragent.override", "some UA string");
WebDriver driver = new FirefoxDriver(profile);

7.9 拖拽Web元素

下面是一個拖拽Web頁面元素的例子,前提是本地事件必須可用。

 

WebElement element = driver.findElement(By.name("source"));
WebElement target = driver.findElement(By.name("target"));

(new Actions(driver)).dragAndDrop(element, target).perform();

 

 

8 各類Driver的特性以及如何選擇合適Driver

翻譯中
 

9 向前兼容:融合WebDriver和Selenium-RC

翻譯中
 

10 爲遠程WebDriver單獨啓動Selenium Server

翻譯中

 

 
      

譯者注:

一、原文連接:http://www.seleniumhq.org/docs/03_webdriver.jsp。

二、文中只包含了java相關的操做,WebDriver還支持c#/Python/Ruby/Perl/PHP/Perl,若有須要,請閱讀原文。

三、language binding,又叫glue code,意思是膠水代碼,好比有個C++的lib庫,java調用這個庫的api就叫java binding。參考:http://en.wikipedia.org/wiki/Language_binding

四、措辭拙劣,有些單詞句子沒有深究就直譯了,深感從閱讀到翻譯差的不只僅是一本字典,還有文化的差別。筆者強烈推薦直接閱讀官網上的原文,若是個人譯文給你形成誤解,深感不安。這也是最後三章不敢繼續班門弄斧的緣由,等我對Selenium熟悉了以後再回來補全。

相關文章
相關標籤/搜索