<h3>一、Xpath定位方法深入探討</h3>
(1)常用的Xpath定位方法及其特點
<h6>使用絕對路徑定位元素体谒。</h6>
例如:
driver.findElement(By.xpath("/html/body/div/form/input"))杯聚。
特點:這個路徑是從網(wǎng)頁起始標簽開始一直到要定位的元素的路徑,如果要定位的元素在頁面最下面抒痒,則這個Xpath路徑會非常長幌绍。如果在要定位的元素與頁面開始之間的元素有任何增減,元素定位就會失敗故响。
<h6>使用相對路徑定位元素傀广。</h6>
例如:
driver. findElement(By.xpath ("http://input") )
返回查找到的第一個符合條件的元素。
特點:相對路徑一般只會包含與被定位元素最近的幾層元素有關(guān)彩届,相對路徑寫的好的話伪冰,頁面變動影響最小,而且定位準確樟蠕。
<h6>使用索引定位元素贮聂,索引的初始值為1,注意與數(shù)組等區(qū)分開寨辩。</h6>
例如:
driver. findElement(By.xpath ("http://input[2]") )
返回查找到的第二個符合條件的元素吓懈。
特點:如果一個頁面中有多個相似的元素,或是一個層下面有多個同樣的元素的時候靡狞,需要用索引的方法來定位耻警,否則無法區(qū)分。
<h6> 結(jié)合屬性值來定位元素。</h6>
例如:
driver. findElement(By.xpath ("http://input[@id='username']"));
driver. findElement(By.xpath ("http://img[@alt='flowr']"));
特點:屬性定位也是比較常用的方法甘穿,如果元素中沒有常見的id,name,class等直接有方法可調(diào)用的屬性腮恩,也可以查找元素中是否有其他能唯一標識元素的屬性,如果有扒磁,就可以用此方法定位庆揪。
<h6> 使用邏輯運算符,結(jié)合屬性值定位元素,and與or妨托。</h6>
例如:
driver.findElement(By.xpath("http://input[@id='username' and @name='userID']"));
特點:多個屬性值聯(lián)合定位缸榛,更能準確定位到元素。并且如果多個相同標簽的元素兰伤,如果其包含的屬性值有不同的内颗,也可以用這個方法區(qū)分開來。
<h6>使用屬性名來定位元素敦腔。</h6>
例如:
driver. findElement(By.xpath ("http://input[@button]"))
特點:此方法可以區(qū)分同一種標簽均澳,含有不同屬性名的元素。定位相對簡單一些兒符衔,但也同樣存在著無法區(qū)分同種標簽含有同種屬性名的多個元素找前,這個時候要配合索引定位才行。
<h6> 類似于cssSlector判族,使用部分屬性值匹配元素.</h6>
例如:
(a)starts-with()
driver. findElement(By.xpath ("http://input[stars-with(@id,'user')]"))
(b)ends-with()
driver. findElement(By.xpath ("http://input[ends-with(@id,'name')]"))
(c)contains()
driver. findElement(By.xpath ("http://input[contains(@id,"ernam")]"))
特點:此方法更加靈活躺盛,可以定位屬性值不太規(guī)律,或是部分變動形帮,中間有空格的情況槽惫。注:如果屬性值中間包含空格,Webdriver定位的時候容易出錯辩撑,時而能定位到時而定位不到界斜,所以應該避免用含用空格的屬性值定位『霞剑可以采用此方法各薇,進行部分屬性值定位。
<h6> 使用任意屬性值匹配元素君躺。</h6>
例如:
driver. findElement(By.xpath ("http://input[@*='username']"))
特點:此方法相當于模糊查詢峭判,只要欲定位的標簽,如input中任何屬性值等于‘username’,就能匹配成功晰洒。缺點朝抖,可能會匹配含有這個屬性值的其他元素啥箭,所以我們在定位的時候要查看一下這個元素值在頁面中是否唯一谍珊。
(2)運用Xpath定位元素的思路
當我們在做自動化測試的時候,欲對一個頁面元素定位,通過上面我們講到的選擇定位方法篩選后砌滞,決定用Xpath定位了侮邀,此時我們應該怎么寫Xpath呢?請按以下步驟來分析:
(a)先看一個這個元素是否有明顯的贝润,唯一的屬性值绊茧。如果有,我們就用相對路徑加屬性值定位打掘,這是最簡單準確的定位方法华畏。如:
//input[@alog-alias=’search’]。
(b)如果要定位的元素尊蚁,不符合上面的特癥亡笑,元素屬性要么是動態(tài)的,要么就是不能區(qū)分這個元素的横朋,還有就是屬性值中間有空格的情況仑乌,都無法定位。所以從此元素開始琴锭,向他的上一層查找晰甚。
(c)當遇到了一個符合條件的元素時,對其寫Xpath决帖,然后在Selenium IDE中驗證是否能定位到該元素厕九。如:
//div[@type=’good’],
在Selenium IDE中驗證能定位到這個div。
(d)然后從這個元素開始古瓤,一級級往下寫止剖,真到要定位的元素為止。如果你比較肯定寫的是正確的落君,可以寫完后再驗證穿香,如果不肯定,就寫一層绎速,用Selenium IDE驗證一下皮获,以確保安全。如:
//div[@type=’good’]/div/input
(e)當Selenium IDE定位成功后纹冤,再放到測試用例中去調(diào)試運行洒宝。雖然Selenium IDE能定位到的代碼也能定位到,不過還有因為延遲萌京,操作順序等會影響代碼定位的因素存在雁歌。
<h3>二、元素定位不到的原因及解決辦法</h3>
在我們編寫自動化測試用例的過程中知残,經(jīng)常會遇到元素定位不到的現(xiàn)象靠瞎,有的時候我們用Selenium IDE檢查的時候也能在Firebug中看到,可是運行代碼的時候,總是提示元素找不到乏盐。經(jīng)過我以往和經(jīng)驗和大家在網(wǎng)上的討論佳窑,我總結(jié)了以下幾種情況:
(1)定位屬性值是動態(tài)變化的情況
現(xiàn)象:在我們定位元素的時候,發(fā)現(xiàn)有id, name或其他的屬性存在父能,于是就用相應的定位方法去定位神凑。可是運行的時候提示定位不到何吝,然后我們再去查看元素的時候溉委,發(fā)現(xiàn)屬性值和我們寫代碼的時候不一樣了。
原因:通常產(chǎn)生這種情況的原因就是你使用的屬性值是動態(tài)變化的爱榕,主要表現(xiàn)有屬性值是一串數(shù)據(jù)薛躬,或是字符加一串數(shù)據(jù)等情況。頁面加載一次變化一次呆细,每次都不相同型宝。
解決辦法:我們應盡量避免用這樣的屬性值去定位,而采用這個元素下的其他固定不變的屬性值絮爷∨亢ǎ或是向上層查找,采用Xpath定位坑夯。
(2)Iframe中的元素定位出錯的情況
現(xiàn)象:我們在定位元素的時候岖寞,查看網(wǎng)頁源碼,發(fā)現(xiàn)有iframe存在柜蜈≌套唬可是我們沒有做特殊處理,而是直接用通用的定位方法淑履,name ,id, xpath或者CSS來定位隶垮。用Selenium IDE驗證能查找到元素,可是運行測試用例的時候秘噪,總是元素找不到狸吞。
原因:在我們運行測試腳本的時候,代碼獲取的是頁面的句柄指煎,而iframe在句柄中是當成一個元素來處理的蹋偏。腳本是沒有辦法自己去iframe中去定位元素的,所以當搜索完頁面時至壤,發(fā)現(xiàn)找不到要定位的元素威始,就當錯誤處理。
解決辦法:當需要定位iframe中的元素的時候像街,先將句柄切換到iframe中
(driver.switchTo().frame("framename");)
然后再去定位黎棠,就能定位到要測試的元素京郑。
(3)不同頁面或iframe切換時元素定位情況
現(xiàn)象:當我們在編寫測試用例的時候,會遇到打開一個新頁面葫掉,或是切換到一個新的iframe中,然后再去定位元素進行操作跟狱。但是我們的定位方法寫的沒有問題俭厚,而且在Selenium IDE中也驗證通過,可是代碼運行的時候還是會提示找不到元素驶臊。
原因:其實這個和定位iframe中元素的情況是一樣的挪挤,在打開一個頁面或是切換到一個iframe的時候,driver獲取的是當前頁面或是iframe的句柄关翎。當你的操作切換到新的頁面或是iframe的時候扛门,如果代碼不去做相應的切換,查找元素的時候還會在原來的句柄下查找纵寝,當然會出現(xiàn)查找不到的情況论寨。
解決辦法:當操作切換頁面或是iframe的時候,我們的測試腳本也要做相應的切換爽茴,選擇新打開的頁面或是切換到新的iframe下葬凳。然后再去定位的時候,就會在新頁面或是iframe下定位了室奏。
(4)Xpath編寫出錯的情況
現(xiàn)象:如果我們對一個元素編寫了對應的Xpath火焰,然后在沒有通過Selenium IDE進行驗證的情況吧,就去編寫代碼執(zhí)行測試用例胧沫。會出現(xiàn)查找不到元素的情況昌简,或是頁面發(fā)生了變化,導致Xpath路徑有了變化绒怨,也會查找不到元素纯赎。
原因:主要的問題就是Xpath編寫出錯了,或是頁面有改動南蹂。不管是增加了新的模塊或是隱藏的div址否,都會影響Xpath路徑的。
解決辦法:將代碼中的Xpath拷出來碎紊,放到Selenium IDE中進行驗證佑附。如果出錯了,就做相應的修改仗考。這個也是代碼維護中當遇到的問題音同,被測試對象變化,導致測試用例的修改秃嗜。
(5)操作速度過快权均,被定位的元素沒有加載出來的情況
現(xiàn)象:在測試用例運行過程中顿膨,會出現(xiàn)被定位的元素有的時候能定位的到,有的時候卻定位不到的現(xiàn)象叽赊。而我們?nèi)ロ撁嫔向炞C我們的定位方法的時候恋沃,沒有一點兒問題,顯示不是定位方法寫錯了必指。
原因:這種情況多半是因為測試用例執(zhí)行到代碼的時候囊咏,被定位元素沒有加載出來造成的。網(wǎng)速原因塔橡,執(zhí)行代碼的機器原因梅割,都會造成加載比程序執(zhí)行的慢的情況。
解決辦法:在我們定位元素之前葛家,評估一下頁面的加載情況户辞,如果有加載慢的地方,需要添加一定等待時間
self.sleep(5000),
等上幾秒后再去定位操作癞谒。
(6)定位頁面嵌入式元素的情況
現(xiàn)象:在頁面中會有一些兒嵌入式元素底燎,如object,播放器等。這個時候弹砚,我們對其操作的時候书蚪,是無法定位到上面的元素的。
原因:嵌入式元素對webdriver來說是一個元素迅栅,不管里面包含多少元素殊校,都無法操作。對于object對象读存,網(wǎng)上有說要對相應的Flash重新編譯为流,添加相應的代碼或是控件才能定位。但這樣一樣又不安全了让簿,所以嵌入式對象一直是自動化測試的盲區(qū)敬察。
解決辦法:嵌入式對象如果是簡單的單擊操作,可是用模擬鼠標單擊相應的區(qū)域尔当,就能完成操作莲祸。如果是輸入操作,我們可以先模擬點擊輸入?yún)^(qū)椭迎,然后模擬鍵盤進行輸入锐帜。除此之外,好像也沒有什么好的辦法畜号。
(7)firefox安全性報錯的情況
現(xiàn)象:firefox安全性強缴阎,不允許跨域調(diào)用出現(xiàn)報錯,錯誤描述:
uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMNSHTMLDocument.execCommand]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location:
原因:這是因為firefox安全性強简软,不允許跨域調(diào)用蛮拔。
解決辦法:Firefox 要取消XMLHttpRequest的跨域限制的話述暂,
第一是從 about:config 里設(shè)置
signed.applets.codebase_principal_support = true; (地址欄輸入about:config
即可進行firefox設(shè)置)建炫。
第二就是在open的代碼函數(shù)前加入類似如下的代碼:
try{
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
}
catch (e)
{
alert("Permission UniversalBrowserRead denied.");
}
對錯誤進行處理畦韭。
喜歡就留下你的贊吧