1. 程式人生 > >元素定位-XPATH定位方法總結

元素定位-XPATH定位方法總結

1、Xpath定位方法探討

xpath是比較常用的一種定位元素的方式,因為它很方便,缺點是,消耗系統性能。如果Xpath使用的比較好,幾乎可以定位到任何頁面元素,而且受頁面變化影響較小。

1.1、什麼是XPATH:

  XPath (XML Path Language) 是一門在 HTML文件中查詢資訊的語言,可用來在 HTML文件中對元素和屬性進行遍歷。

        詳細使用方法可見 W3School官方文件:http://www.w3school.com.cn/xpath/index.asp

1.2、XPATH節點選擇方式

1)Chrome外掛工具:Xpath helper可以驗證定位元素的位置準確性、可以檢視某個元素的xpath路徑,但路徑通常較長不建議此方式

2)Chrome瀏覽器:滑鼠右鍵copy->Copy Xpath直接複製某個元素xpath路徑(常用方式)

3)手動編寫xpath路徑:方式二不能滿足所有情況,需要手動微調路徑藉助方式一來驗證

1.3、XPATH節點定位方法與特點

  • 使用絕對路徑定位元素

  例如:driver.findElement(By.xpath("/html/body/div/form/input"))。

  特點:這個路徑是從網頁起始標籤開始一直到要定位的元素的路徑,如果要定位的元素在頁面最下面,則這個Xpath路徑會非常長。如果在要定位的元素與頁面開始之間的元素有任何增減,元素定位就會失敗。

  • 使用相對路徑定位元素

  例如:driver. findElement(By.xpath ("//input") ) 返回查詢到的第一個符合條件的元素。

  特點:相對路徑一般只會包含與被定位元素最近的幾層元素有關,相對路徑寫的好的話,頁面變動影響最小,而且定位準確。

  • 使用索引定位元素,索引的初始值為1,注意與陣列等區分開。

  例如:driver. findElement(By.xpath ("//input[2]") )返回查詢到的第二個符合條件的元素。

  特點:如果一個頁面中有多個相似的元素,或是一個層下面有多個同樣的元素的時候,需要用索引的方法來定位,否則無法區分。

  • 結合屬性值來定位元素。

  例如:driver. findElement(By.xpath ("//input[@id='username']"));

     driver. findElement(By.xpath ("//img[@alt='flowr']"));

  特點:屬性定位也是比較常用的方法,如果元素中沒有常見的id,name,class等直接有方法可呼叫的屬性,也可以查詢元素中是否有其他能唯一標識元素的屬性,如果有,就可以用此方法定位。

  • 使用邏輯運算子,結合屬性值定位元素,and與or。

  例如:driver.findElement(By.xpath("//input[@id='username' and @name='userID']"));

  特點:多個屬性值聯合定位,更能準確定位到元素。並且如果多個相同標籤的元素,如果其包含的屬性值有不同的,也可以用這個方法區分開來。

  • 使用屬性名來定位元素。

  例如:driver. findElement(By.xpath ("//input[@button]"))

  特點:此方法可以區分同一種標籤,含有不同屬性名的元素。定位相對簡單一些兒,但也同樣存在著無法區分同種標籤含有同種屬性名的多個元素,這個時候要配合索引定位才行。

  • 使用部分屬性值模糊匹配元素.

  例如:

  (a)starts-with()  

    //input[starts-with(@id,"kw")]

    //div[starts-with(@id,"u_sp")]/a[1]

  (b)contains()      

  例如://input[contains(@id,"kw")]

  特點:此方法更加靈活,可以定位屬性值不太規律,或是部分變動,中間有空格的情況。注:如果屬性值中間包含空格,Webdriver定位的時候容易出錯,時而能定位到時而定位不到,所以應該避免用含用空格的屬性值定位。可以採用此方法,進行部分屬性值定位。

  • 使用任意屬性值匹配元素。

  例如:driver. findElement(By.xpath ("//input[@*='username']"))

  特點:此方法相當於模糊查詢,只要欲定位的標籤,如input中任何屬性值等於‘username’,就能匹配成功。缺點,可能會匹配含有這個屬性值的其他元素,所以我們在定位的時候要檢視一下這個元素值在頁面中是否唯一。

1.4、運用Xpath定位元素的思路

當我們在做自動化測試的時候,想要對一個頁面元素定位,通過上面我們講到的選擇定位方法篩選後,決定用Xpath定位了,此時我們應該怎麼寫Xpath呢?請按以下步驟來分析:

(a)先看一個這個元素是否有明顯的,唯一的屬性值。如果有,我們就用相對路徑加屬性值定位,這是最簡單準確的定位方法。如://input[@alog-alias=’search’]。

(b)如果要定位的元素,不符合上面的特症,元素屬性要麼是動態的,要麼就是不能區分這個元素的,還有就是屬性值中間有空格的情況,都無法定位。所以從此元素開始,向他的上一層查詢。

(c)當遇到了一個符合條件的元素時,對其寫Xpath,然後在Selenium IDE(或者xpath helper)中驗證是否能定位到該元素。如://div[@type=’good’],在Selenium IDE中驗證能定位到這個div。

(d)然後從這個元素開始,一級級往下寫,真到要定位的元素為止。如果你比較肯定寫的是正確的,可以寫完後再驗證,如果不肯定,就寫一層,用Selenium IDE驗證一下,以確保安全。如://div[@type=’good’]/div/input

(e)當Selenium IDE定位成功後,再放到測試用例中去除錯執行。雖然Selenium IDE能定位到的程式碼也能定位到,不過還有因為延遲,操作順序等會影響程式碼定位的因素存在。

1.5、元素定位不到的原因及解決辦法

在我們編寫自動化測試用例的過程中,經常會遇到元素定位不到的現象,有的時候我們用Selenium IDE檢查的時候也能在Firebug中看到,可是執行程式碼的時候,總是提示元素找不到。經過我以往和經驗和大家在網上的討論,總結了以下幾種情況:

(1)定位屬性值是動態變化的情況(常見問題)

現象:在我們定位元素的時候,發現有id, name或其他的屬性存在,於是就用相應的定位方法去定位。可是執行的時候提示定位不到,然後我們再去檢視元素的時候,發現屬性值和我們寫程式碼的時候不一樣了。

原因:通常產生這種情況的原因就是你使用的屬性值是動態變化的,主要表現有屬性值是一串資料,或是字元加一串資料等情況。頁面載入一次變化一次,每次都不相同。

解決辦法:我們應儘量避免用這樣的屬性值去定位,而採用這個元素下的其他固定不變的屬性值。或是向上層查詢,採用Xpath定位。

(2)Iframe中的元素定位出錯的情況

現象:我們在定位元素的時候,檢視網頁原始碼,發現有iframe存在。可是我們沒有做特殊處理,而是直接用通用的定位方法,name ,id,  xpath或者CSS來定位。用Selenium IDE驗證能查詢到元素,可是執行測試用例的時候,總是元素找不到。

原因:在我們執行測試指令碼的時候,程式碼獲取的是頁面的控制代碼,而iframe在控制代碼中是當成一個元素來處理的。指令碼是沒有辦法自己去iframe中去定位元素的,所以當搜尋完頁面時,發現找不到要定位的元素,就當錯誤處理。

解決辦法:當需要定位iframe中的元素的時候,先將控制代碼切換到iframe中(driver.switchTo().frame("framename");),然後再去定位,就能定位到要測試的元素。

(3)不同頁面或iframe切換時元素定位情況

現象:當我們在編寫測試用例的時候,會遇到開啟一個新頁面,或是切換到一個新的iframe中,然後再去定位元素進行操作。但是我們的定位方法寫的沒有問題,而且在Selenium IDE中也驗證通過,可是程式碼執行的時候還是會提示找不到元素。

原因:其實這個和定位iframe中元素的情況是一樣的,在開啟一個頁面或是切換到一個iframe的時候,driver獲取的是當前頁面或是iframe的控制代碼。當你的操作切換到新的頁面或是iframe的時候,如果程式碼不去做相應的切換,查詢元素的時候還會在原來的控制代碼下查詢,當然會出現查詢不到的情況。

解決辦法:當操作切換頁面或是iframe的時候,我們的測試指令碼也要做相應的切換,選擇新開啟的頁面或是切換到新的iframe下。然後再去定位的時候,就會在新頁面或是iframe下定位了。

(4)Xpath編寫出錯的情況(常見問題)

現象:如果我們對一個元素編寫了對應的Xpath,然後在沒有通過Selenium IDE進行驗證的情況吧,就去編寫程式碼執行測試用例。會出現查詢不到元素的情況,或是頁面發生了變化,導致Xpath路徑有了變化,也會查詢不到元素。

原因:主要的問題就是Xpath編寫出錯了,或是頁面有改動。不管是增加了新的模組或是隱藏的div,都會影響Xpath路徑的。

解決辦法:將程式碼中的Xpath拷出來,放到Selenium IDE中進行驗證。如果出錯了,就做相應的修改。這個也是程式碼維護中當遇到的問題,被測試物件變化,導致測試用例的修改。

(5)操作速度過快,被定位的元素沒有加載出來的情況(常見問題)

現象:在測試用例執行過程中,會出現被定位的元素有的時候能定位的到,有的時候卻定位不到的現象。而我們去頁面上驗證我們的定位方法的時候,沒有一點兒問題,顯示不是定位方法寫錯了。

原因:這種情況多半是因為測試用例執行到程式碼的時候,被定位元素沒有加載出來造成的。網速原因,執行程式碼的機器原因,都會造成載入比程式執行的慢的情況。

解決辦法:在我們定位元素之前,評估一下頁面的載入情況,如果有載入慢的地方,需要新增一定等待時間self.sleep(5000),等上幾秒後再去定位操作。

(6)定位頁面嵌入式元素的情況(很少遇到)

現象:在頁面中會有一些兒嵌入式元素,如object,播放器等。這個時候,我們對其操作的時候,是無法定位到上面的元素的。

原因:嵌入式元素對webdriver來說是一個元素,不管裡面包含多少元素,都無法操作。對於object物件,網上有說要對相應的Flash重新編譯,新增相應的程式碼或是控制元件才能定位。但這樣一樣又不安全了,所以嵌入式物件一直是自動化測試的盲區。

解決辦法:嵌入式物件如果是簡單的單擊操作,可是用模擬滑鼠單擊相應的區域,就能完成操作。如果是輸入操作,我們可以先模擬點選輸入區,然後模擬鍵盤進行輸入。除此之外,好像也沒有什麼好的辦法。