Selenium 自動化測試從零實戰

GitChat技術雜談發表於2017-11-20

[運營專題]零預算引爆個人和企業品牌【原文連結】
原來這樣做,才能向架構師靠近【原文連結】
Cordova App 打包全揭祕【原文連結】
TensorFlow on Android:物體識別【原文連結】
TensorFlow on Android:訓練模式【原文連結】
圖解敏捷教練和 ScrumMaster【原文連結】

說在前面:達人課是GitChat的一款輕閱讀產品,由特約講師獨家釋出。每一個課程你都可獲得6-12篇的深度文章,同時可在讀者圈與講師互動交流。GitChat達人課,讓技術分享更簡單。進入我的GitChat

這裡寫圖片描述

作者簡介

本文作者就職於中科軟科技股份有限公司高階測試工程師-王海寶(勇氣老師),3年以上軟體測試經驗,擅長介面測試、自動化測試,對分散式測試有獨到的見解,擅長測試分析。下面一起看看勇氣老師如何帶大家從零開始。檢視原文

課程簡介

本課程注重自動化實踐,同時講解一些基礎的自動化測試理念,以及常用的 Java 思維,以便快速理解並掌握自動化測試體系、掌握自動化測試的基礎核心內容以及自動化框架的整合實現。以“亞馬遜購物流程”為例,著重講解呼叫被測元素、測試框架 TestNG 的使用,儘量做到讓剛入門自動化的讀者也能感受到自動化的魅力。

導讀:自動化定位解析

寫在前面的話

測試自動化是現在的一種趨勢,更是許多厭倦功能測試想轉型高階測試的測試從業者的迫切需求。關於測試自動化的資料比比皆是,但是雜亂無章,而且好多知識只是一帶而過,並且更多針對 Selenium 這塊的測試以 Python 語言居多,Java 語言很少。其實,Java 語言更加靈活,畢竟面嚮物件語言中 Java 才是當之無愧的王者。

怎樣良好的整合 Java 知識與 Selenium 完美結合,是本課要講解的內容,同時,會以實際案例來逐步引出 Selenium 的使用。課程主要有以下特色:

(1)內容由淺入深,零基礎自動化人員也能看得懂。

(2)始終以解決實際問題為出發點,通過實際案例引出 Selenium 的相關知識,最大限度的避免課程枯燥,用生動的語言來描述自動化。

(3)細化每個實施的細節,希望講解一個知識點就能徹底的講透,並且會以一種由淺入深的形式進行講解。

說了這麼多,希望讀者閱讀完全部文章後會以最大限度的掌握自動化,並且愛上自動化!好了,下面開始步入正題。

準備工作

“工欲善其事必先利其器”,做自動化也是如此,所以先花一點時間來介紹要準備的工作。

(1)軟體工具準備:JDK 和 Eclipse,搭建 Java 的開發環境,需要注意的是二者的版本必須統一,即 32 位的 JDK 必須對應 32 位的 Eclipse。

(2)框架軟體準備:TestNG

安裝方式有兩種:

  • help-Eclipse Markplace 市場查詢下載安裝。 在 TestNG 官網上下載對應版本的外掛,help-Install
  • new Software 安裝已經下載好的外掛。

當然所有的外掛安裝都是這兩種方式。

(3)Foxfire(火狐瀏覽器,建議使用 30~32 版本,目前最新的版本相容性不好且對外掛的支援不夠理想)。在火狐瀏覽器裡要下載其外掛,必須使用的有:

  • Firebug+firepath 用來輔助我們進行元素定位。
  • Selenium IDE 主要用來驗證自動化指令碼是不是與實際情況一致。

需要說明的是,Selenium IDE 本身就有用來做簡單 UI 介面錄製回放的功能。

(4)Google Chrome(谷歌瀏覽器),演示的時候可能只呼叫火狐瀏覽器,但是谷歌瀏覽器是當前 UI 自動化測試的首選,因為其穩定,外掛更新快。

(5)必要的 jar 包

  • log4j-1.2.11.jar,用來支援日誌功能的 jar。
  • selenium-server-standalone-2.43.1.jar,核心 jar 必須要有。

(6)瀏覽器必要的 driver

  • 谷歌的 chromedriver.exe。
  • IE 的 IEDriverServer64.exe。
  • Windows 10 自帶的 Microsoft Edge 的 Microsoft WebDriver。

寫到這裡有可能會問,為什麼需要這麼多的 driver,其實如果只針對一套流程進行自動化操作,只需要操作一個瀏覽器即可,但是如果想用同一個流程驗證不同瀏覽器的相容性時,那麼需要同時啟動多個瀏覽器,所以提前準備好主流瀏覽器的 driver,對我們的工作來說是非常有必要的。

上面的工作全都完成,在 Eclipse 裡建立一個純淨的自動化工作目錄,將下載好的外掛、驅動、jar 都配置好,此時 Eclipse 的工程目錄如下圖所示:
這裡寫圖片描述

其中 files 是新建的目錄,用來儲存各種瀏覽器的驅動。lib 也是新建的目錄,用來儲存各種 jar 包。當然,這兩個檔案的名稱都可以自行改變。好了準備工作到此結束,下面進行定位的講解。

定位實戰
- UI 自動化的實質其實就是做下面兩件事情:
- 定位到 Web 介面的被測試元素;
對定位到的元素進行錄入、單擊、雙擊、拖拽、上傳檔案、清空等等操作的過程。

請看下面的例子。
(1)開啟百度網站的首頁:
這裡寫圖片描述

(2)在輸入框輸入 GitChat:

這裡寫圖片描述

此場景運用自動化的思維解決就是:首先要開啟一個瀏覽器 | 在導航欄處輸入百度的網址 | 定位到輸入框 | 鍵盤敲入 GitChat 的過程。操作火狐瀏覽器實現 Java 程式碼如下:

package com.test.baidu;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class Baidu {
public static void main(String[] args) {
        //啟動火狐瀏覽器
        WebDriver driver = new FirefoxDriver();
        //將導航欄導航到百度首頁
        driver.navigate().to("http://www.baidu.com");
        //定位到輸入框
        WebElement element = driver.findElement(By.id("kw"));
        //輸入 GitChat
        element.sendKeys("GitChat");
    }
}

這裡重點先講解裡面的定位問題:

WebElement element = driver.findElement(By.id("kw"));

定位方式

常用的定位方式如下:

這裡寫圖片描述

這些都是常用的定位方式,有 by.id、by.name、by.cssSelector、by.xpath 等等。其中除了 by.cssSelector、by.xpath 外,其他的 by 後面的 id、name、link Text 等指的是 HTML 標記語言中頁籤內的屬性內容,如百度輸入框的 HTML 原始碼如下:

<span class="bg s_ipt_wr quickdelete-wrap ipthover">
<span class="soutu-btn"/>
<input id="kw" class="s_ipt" autocomplete="off" maxlength="255" value="" name="wd"/>
<a id="quickdelete" class="quickdelete" href="javascript:;" title="清空" style="top: 0px; right: 0px; display: none;"/>
</span>

這段程式碼裡的 class、id 就是屬性。所以針對百度輸入框我們使用的是其 id 的屬性。

xpath 定位

首先要明白為什麼使用 xpath 定位,它的好處有如下幾個方面:

  • 方便維護
  • 定位準確
  • 推薦以後大家無論任何被測試物件都採用 xpath 定位的方式

其次需要了解 xpath 常用符號說明,常用的符號及含義如下所示:
- /:表示絕對路徑,絕對路徑是指從跟目錄開始
- //:表示相對路徑
- .:表示當前層
- ..:表示上一層
- *:表示萬用字元
- @:表示屬性
- []:屬性的判斷條件表示式

最後運用上面的符號結合 xapth 的相關語法進行定位演示。

演示場景

任找一個 HTML 網頁進行定位實戰,按照頁面程式碼結構逐級定位得出的結果解釋如下,希望通過下面的逐級定位內容能理解相對路徑、HTML 的層級結構。

(1)/html/div:沒有節點可以被選擇,因為 / 代表絕對路徑,本定位表示的是 HTML 下一級目錄的元素,很明顯 HTML 的下一級是 head 和 body,所以本寫法無法定位到任何元素。

(2)/html//div:選中 HTML 標籤中的所有 div 元素,// 相對路徑。就完全等價於 //div 的寫法。

(3)//div/div 表示所選擇的 div 元素下又包含 div 元素的所有元素。此時完全等價於 //div/div/. 的寫法。

(4)//div/div/..:表示 //div/div 定義到的上一層 div 上。

(5)//div/div/*:此時會將 div 下的子節點含有 div 的這層節點下的所有元素都匹配到。

(6)//div[@id=”input”]:此時表示在 div 目錄下選擇一個 id=input 的子節點。

and 與 or 連線符在 xpath 中的使用

and 的使用:此種定位的應用場景為下圖所示:

這裡寫圖片描述

此種場景的 HTML 編碼為:

<td class="widgetStyle">
<div id="radio">
<input class="Volvo" type="radio" name="identity"/>
<label>Volvo</label>
<br/>
<input class="Saab" type="radio" name="identity"/>
<label>Saab</label>
<br/>
<input class="Opel" type="radio" name="identity"/>
<label>Opel</label>
<br/>
<input class="Audi" type="radio" name="identity"/>
<label>Audi</label>
</div>

此時我們想定位到 Saab 怎麼寫呢?(當然也可以不使用 and 連線符進行書寫)書寫為://input[@class=”Saab” and @name=”identity”],當然若寫成 //input[@class=”Saab”] 肯定也不會有問題。

or 的使用:如果定位到 Saab 或者定位到 Opel,此時書寫方式為://input[@class=”Saab” or @class=”Opel”]。

定位順序(從1開始切記)

現在學習第二種方式,比如定位 Saab。可以這樣寫://input@name=’identity’,同理定位 Volvo,//input@name=’identity’(這就是一開始強調的,這種寫法必須從 1 開始編號)。

  • 定位 Opel,寫成://input@name=’identity’
  • 定位 Audi,寫成://input@name=’identity’

常用函式

Xpath 定位還可以使用一些函式,常用的函式如下:

(1)contains():包含。若要匹配出 Saab 還可以這樣寫://input[@name=”identity” and contains(@class,’S’)]

(2)text():一個節點的文字值。舉個例子,這裡面籃字顯示的英文結果,HTML 程式碼為:

<a target="_self" href="/s?rsv_idx=1&amp;wd=111&amp;usm=3&amp;ie=utf-8&amp;sl_lang=en&amp;rsv_srlang=en&amp;rsv_rq=en&amp;rqlang=cn">英文結果</a>

可見這四個字沒有任何屬性值資訊,所以定位此資訊的時候需要使用 text() 函式。場景如下圖所示:

這裡寫圖片描述

此時定位英文結果即可使用://a[text()=”英文結果”]

(3)last()函式,定位 Audi 寫成 //input@name=’identity’,可以看到 Audi 這個元素本身就處於 input 最後一個了,此時可以使用 last() 函式進行匹配://input[@name=”identity”][last()]。

(4)starts-with:以 starts-with 為開頭寫法例項://input[starts-with(@id,’user’)]代表 input 下 id 以 user 為開頭的元素。

(5)not():表示否定,一般情況下會與返回值為 true 或者 false 的函式組合起來使用。比如上面提到的 contains() 與 starts-with。

用例項來說:現在想要定位到不是 Audi 車除外的三種車元素,此時寫法為://input[@name=”identity” and not (contains(@class,’A’))]。

當然 not() 還有一種特殊用法就是直接 Not。//input[not(@class)] 表示匹配出 input 下所有不含 class 屬性的元素。

總結:唯一需要注意的是所有函式的寫法 function(@屬性,’內容’)。

Xpath 軸定位說明

(1)基本軸

軸可以在位置路徑中快捷引用特定的節點(忽略屬性和名稱空間節點)。child 例子:

 "child::*"
     當前節點的子節點。  
    "child::childnodename"
     當前節點名為childnodename的子節點。
    "child::text()" 
     當前節點文字子節點。 
    "child::node()"
     當前節點的子節點。
    "child::*/child::nodename"
     取當前節點的子節點的名為nodename的子節點。

(2)特殊軸

self 當前節點

descendant 當前節點的後代(子節點或子節點的子節點…)

parent 當前節點的父節點

ancestor 當前節點的祖先節點(父節點和父節點的父節點…)

preceding 按文件順序位於當前節點之前的非祖先節點

attribute 當前節點的屬性

namespace 當前節點的名稱空間

preceding-sibling 當前節點之前的所有兄弟節點

following 當前節點之後的所有節點

following-sibling 當前節點之後的所有兄弟節點

descendant-or-self 當前節點和後代節點

ancestor-or-self 當前節點和祖先節點

以上的兩種軸型別,沒什麼好說的,先記住吧。具體怎麼用請看下面例項。

第一個例項:繼續定位上述中的 Volvo,使用 xpath 軸書寫如下://div[@id=”radio”]/descendant::input1 也可以定位到。

第二個例項:定義 Audi 上的所有節點,使用 xpath 軸寫法如下://input[@name=”identity” and @class=”Audi”]/preceding-sibling::*

(3)需要注意的幾個問題。

[] 後面需要跟 /,/ 後面在加上關鍵字。

軸關鍵字後面必須使用 ::,這個後面可以接節點名稱,如 input、div 等。如果後面跟的是 *,代表全部。

軸後面接節點名稱是節點前面的定位方式全部可以繼續適用。

對於軸的使用建議是能不用就不用,條條大路通羅馬,沒必要非使用軸進行定位。

cssSelector 定位

瞭解即可,能用 xpath 就不用 cssSelector。原因很簡單,HTML 的程式碼我們更熟悉。

CSS 常用符號說明

  • #表示 id
  • .表示class
  • : 表示子元素,層級

值得注意的是:一個空格也表示子元素,但是所有的後代子元素,就相當於 xpath 中的相對路徑。

想知道所有的 CSS 屬性建議搜尋其他資料學習下。

最後請記住定位沒有最好,只有是否合適。選擇最合適的定位方法,就能使得定位變得得心應手。

下一篇

課程內容

導讀:自動化定位解析

第01課:自動化程式設計的兩大重點

第02課:基於 Selenium 3.0 啟動與配置瀏覽器

第03課:亞馬遜購物流程實戰

第04課:亞馬遜購物流程分析

第05課:工程化整合自動化程式碼

第06課:TestNG 與斷言類的使用

第07課:Page Object 自動化框架實施

相關文章