(1)經常使用的Xpath定位方法及其特色css
例如:html
driver.findElement(By.xpath("/html/body/div/form/input"))。
特色:這個路徑是從網頁起始標籤開始一直到要定位的元素的路徑,若是要定位的元素在頁面最下面,則這個Xpath路徑會很是長。若是在要定位的元素與頁面開始之間的元素有任何增減,元素定位就會失敗。web
例如:跨域
driver. findElement(By.xpath ("//input") )
返回查找到的第一個符合條件的元素。數組
特色:相對路徑通常只會包含與被定位元素最近的幾層元素有關,相對路徑寫的好的話,頁面變更影響最小,並且定位準確。安全
例如:app
driver. findElement(By.xpath ("//input[2]") )
返回查找到的第二個符合條件的元素。
特色:若是一個頁面中有多個類似的元素,或是一個層下面有多個一樣的元素的時候,須要用索引的方法來定位,不然沒法區分。函數
例如:測試
driver. findElement(By.xpath ("//input[@id='username']")); driver. findElement(By.xpath ("//img[@alt='flowr']"));
特色:屬性定位也是比較經常使用的方法,若是元素中沒有常見的id,name,class等直接有方法可調用的屬性,也能夠查找元素中是否有其餘能惟一標識元素的屬性,若是有,就能夠用此方法定位。firefox
例如:
driver.findElement(By.xpath("//input[@id='username' and @name='userID']"));
特色:多個屬性值聯合定位,更能準肯定位到元素。而且若是多個相同標籤的元素,若是其包含的屬性值有不一樣的,也能夠用這個方法區分開來。
例如:
driver. findElement(By.xpath ("//input[@button]"))
特色:此方法能夠區分同一種標籤,含有不一樣屬性名的元素。定位相對簡單一些兒,但也一樣存在着沒法區分同種標籤含有同種屬性名的多個元素,這個時候要配合索引定位才行。
例如:
(a)starts-with()
driver. findElement(By.xpath ("//input[stars-with(@id,'user')]"))
(b)ends-with()
driver. findElement(By.xpath ("//input[ends-with(@id,'name')]"))
(c)contains()
driver. findElement(By.xpath ("//input[contains(@id,"ernam")]"))
特色:此方法更加靈活,能夠定位屬性值不太規律,或是部分變更,中間有空格的狀況。注:若是屬性值中間包含空格,Webdriver定位的時候容易出錯,時而能定位到時而定位不到,因此應該避免用含用空格的屬性值定位。能夠採用此方法,進行部分屬性值定位。
例如:
driver. findElement(By.xpath ("//input[@*='username']"))
特色:此方法至關於模糊查詢,只要欲定位的標籤,如input中任何屬性值等於‘username’,就能匹配成功。缺點,可能會匹配含有這個屬性值的其餘元素,因此咱們在定位的時候要查看一下這個元素值在頁面中是否惟一。
(2)運用Xpath定位元素的思路
當咱們在作自動化測試的時候,欲對一個頁面元素定位,經過上面咱們講到的選擇定位方法篩選後,決定用Xpath定位了,此時咱們應該怎麼寫Xpath呢?請按如下步驟來分析:
(a)先看一個這個元素是否有明顯的,惟一的屬性值。若是有,咱們就用相對路徑加屬性值定位,這是最簡單準確的定位方法。如:
//input[@alog-alias=’search’]。
(b)若是要定位的元素,不符合上面的特症,元素屬性要麼是動態的,要麼就是不能區分這個元素的,還有就是屬性值中間有空格的狀況,都沒法定位。因此今後元素開始,向他的上一層查找。
(c)當遇到了一個符合條件的元素時,對其寫Xpath,而後在Selenium IDE中驗證是否能定位到該元素。如:
//div[@type=’good’],
在Selenium IDE中驗證能定位到這個div。
(d)而後從這個元素開始,一級級往下寫,真到要定位的元素爲止。若是你比較確定寫的是正確的,能夠寫完後再驗證,若是不願定,就寫一層,用Selenium IDE驗證一下,以確保安全。如:
//div[@type=’good’]/div/input
(e)當Selenium IDE定位成功後,再放到測試用例中去調試運行。雖然Selenium IDE能定位到的代碼也能定位到,不過還有由於延遲,操做順序等會影響代碼定位的因素存在。
在咱們編寫自動化測試用例的過程當中,常常會遇到元素定位不到的現象,有的時候咱們用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從新編譯,添加相應的代碼或是控件才能定位。但這樣同樣又不安全了,因此嵌入式對象一直是自動化測試的盲區。
解決辦法:嵌入式對象若是是簡單的單擊操做,但是用模擬鼠標單擊相應的區域,就能完成操做。若是是輸入操做,咱們能夠先模擬點擊輸入區,而後模擬鍵盤進行輸入。除此以外,好像也沒有什麼好的辦法。
(7)firefox安全性報錯的狀況
現象:firefox安全性強,不容許跨域調用出現報錯,錯誤描述:
uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMNSHTMLDocument.execCommand]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location:
緣由:這是由於firefox安全性強,不容許跨域調用。
解決辦法:Firefox 要取消XMLHttpRequest的跨域限制的話,
第一是從 about:config 裏設置
signed.applets.codebase_principal_support = true; (地址欄輸入about:config
便可進行firefox設置)。
第二就是在open的代碼函數前加入相似以下的代碼:
try{ netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } catch (e) { alert("Permission UniversalBrowserRead denied."); }
對錯誤進行處理。