您的位置:軟件測試 > 開源軟件測試 > 開源功能測試工具 > Selenium
Selenium Webdriver元素定位的八種常用方式
作者:測試控 發(fā)布時(shí)間:[ 2016/6/30 13:34:40 ] 推薦標(biāo)簽:功能測試工具 軟件測試

  7. By.xpath()
  這個(gè)方法是非常強(qiáng)大的元素查找方式,使用這種方法幾乎可以定位到頁面上的任意元素。在正式開始使用XPath進(jìn)行定位前,我們先了解下什么是XPath。XPath是XML Path的簡稱,由于HTML文檔本身是一個(gè)標(biāo)準(zhǔn)的XML頁面,所以我們可以使用XPath的語法來定位頁面元素。
  假設(shè)我們現(xiàn)在以圖(2)所示HTML代碼為例,要引用對應(yīng)的對象,XPath語法如下:


  圖(2)

  路徑寫法(只有一種),寫法如下:
  引用頁面上的form元素(即源碼中的第3行):/html/body/form[1]
  注意:1. 元素的xpath路徑可通過firebug直接查詢。2. 一般不推薦使用路徑的寫法,因?yàn)橐坏╉撁娼Y(jié)構(gòu)發(fā)生變化,該路徑也隨之失效,必須重新寫。3. 路徑以單/號表示,而下面要講的相對路徑則以//表示,這個(gè)區(qū)別非常重要。另外需要多說一句的是,當(dāng)xpath的路徑以/開頭時(shí),表示讓Xpath解析引擎從文檔的根節(jié)點(diǎn)開始解析。當(dāng)xpath路徑以//開頭時(shí),則表示讓xpath引擎從文檔的任意符合的元素節(jié)點(diǎn)開始進(jìn)行解析。而當(dāng)/出現(xiàn)在xpath路徑中時(shí),則表示尋找父節(jié)點(diǎn)的直接子節(jié)點(diǎn),當(dāng)//出現(xiàn)在xpath路徑中時(shí),表示尋找父節(jié)點(diǎn)下任意符合條件的子節(jié)點(diǎn),不管嵌套了多少層級(這些下面都有例子,大家可以參照來試驗(yàn))。弄清這個(gè)原則,可以理解其實(shí)xpath的路徑可以路徑和相對路徑混合在一起來進(jìn)行表示,想怎么玩怎么玩。
  下面是相對路徑的引用寫法:
  查找頁面根元素://
  查找頁面上所有的input元素://input
  查找頁面上第一個(gè)form元素內(nèi)的直接子input元素(即只包括form元素的下一級input元素,使用路徑表示,單/號)://form[1]/input
  查找頁面上第一個(gè)form元素內(nèi)的所有子input元素(只要在form元素內(nèi)的input都算,不管還嵌套了多少個(gè)其他標(biāo)簽,使用相對路徑表示,雙//號)://form[1]//input
  查找頁面上第一個(gè)form元素://form[1]
  查找頁面上id為loginForm的form元素://form[@id='loginForm']
  查找頁面上具有name屬性為username的input元素://input[@name='username']
  查找頁面上id為loginForm的form元素下的第一個(gè)input元素://form[@id='loginForm']/input[1]
  查找頁面具有name屬性為contiune并且type屬性為button的input元素://input[@name='continue'][@type='button']
  查找頁面上id為loginForm的form元素下第4個(gè)input元素://form[@id='loginForm']/input[4]
  Xpath功能很強(qiáng)大,所以也可以寫得更加復(fù)雜一些,如下面圖(3)的HTML源碼。


  圖(3)

  如果我們現(xiàn)在要引用id為“J_password”的input元素,該怎么寫呢?我們可以像下面這樣寫:
  WebElement password = driver.findElement(By.xpath("//*[@id='J_login_form']/dl/dt/input[@id='J_password']"));
  也可以寫成:
  WebElement password = driver.findElement(By.xpath("//*[@id='J_login_form']/*/*/input[@id='J_password']"));
  這里解釋一下,其中//*[@id=’ J_login_form’]這一段是指在根元素下查找任意id為J_login_form的元素,此時(shí)相當(dāng)于引用到了form元素。后面的路徑必須按照源碼的層級依次往下寫。按照圖(3)所示代碼中,我們要找的input元素包含在一個(gè)dt標(biāo)簽內(nèi),而dt又包含在dl標(biāo)簽內(nèi),所以中間必須寫上dl和dt兩層,才到input這層。當(dāng)然我們也可以用*號省略具體的標(biāo)簽名稱,但元素的層級關(guān)系必須體現(xiàn)出來,比如我們不能寫成//*[@id='J_login_form']/input[@id='J_password'],這樣肯定會報(bào)錯(cuò)的。
  前面講的都是xpath中基于準(zhǔn)確元素屬性的定位,其實(shí)xpath作為定位神器也可以用于模糊匹配。比如下面圖(4)所示代碼:


  圖(4)

  這段代碼中的“退出”這個(gè)超鏈接,沒有標(biāo)準(zhǔn)id元素,只有一個(gè)rel和href,不是很好定位。不妨我們用xpath的幾種模糊匹配模式來定位它吧,主要有三種方式,舉例如下。
  a. 用contains關(guān)鍵字,定位代碼如下:
  1 driver.findElement(By.xpath(“//a[contains(@href, ‘logout’)]”));
  這句話的意思是尋找頁面中href屬性值包含有l(wèi)ogout這個(gè)單詞的所有a元素,由于這個(gè)退出按鈕的href屬性里肯定會包含logout,所以這種方式是可行的,也會經(jīng)常用到。其中@后面可以跟該元素任意的屬性名。
  b. 用start-with,定位代碼如下:
  1 driver.findElement(By.xpath(“//a[starts-with(@rel, ‘nofo’)]));
  這句的意思是尋找rel屬性以nofo開頭的a元素。其中@后面的rel可以替換成元素的任意其他屬性。
  c. 用Text關(guān)鍵字,定位代碼如下:
  1 driver.findElement(By.xpath(“//*[text()=’退出’]));
  這個(gè)方法可謂相當(dāng)霸氣啊。直接查找頁面當(dāng)中所有的退出二字,根本不用知道它是個(gè)a元素了。這種方法也經(jīng)常用于純文字的查找。
  另外,如果知道超鏈接元素的文本內(nèi)容,也可以用
  1 driver.findElement(By.xpath(“//a[contains(text(), ’退出’)]));
  這種方式一般用于知道超鏈接上顯示的部分或全部文本信息時(shí),可以使用。
  后,關(guān)于xpath這種定位方式,webdriver會將整個(gè)頁面的所有元素進(jìn)行掃描以定位我們所需要的元素,所以這是一個(gè)非常費(fèi)時(shí)的操作,如果你的腳本中大量使用xpath做元素定位的話,將導(dǎo)致你的腳本執(zhí)行速度大大降低,所以請慎用。
  8. By.cssSelector()
  cssSelector這種元素定位方式跟xpath比較類似,但執(zhí)行速度較快,而且各種瀏覽器對它的支持都相當(dāng)?shù)轿,所以功能也是蠻強(qiáng)大的。
  下面是一些常見的cssSelector的定位方式:
  定位id為flrs的div元素,可以寫成:#flrs     注:相當(dāng)于xpath語法的//div[@id=’flrs’]
  定位id為flrs下的a元素,可以寫成 #flrs > a  注:相當(dāng)于xpath語法的//div[@id=’flrs’]/a
  定位id為flrs下的href屬性值為/forexample/about.html的元素,可以寫成: #flrs > a[href=”/forexample/about.html”]
  如果需要指定多個(gè)屬性值時(shí),可以逐一加在后面,如#flrs > input[name=”username”][type=”text”]。
  明白基本語法后,我們來嘗試用cssSelector方式來引用圖(3)中選中的那個(gè)input對象,代碼如下:
  WebElement password = driver.findElement(By.cssSelector("#J_login_form>dl>dt>input[id=’ J_password’]"));
  同樣必須注意層級關(guān)系,這個(gè)不能省略。
  cssSelector還有一個(gè)用處是定位使用了復(fù)合樣式表的元素,之前在第4種方式className里面提到過,F(xiàn)在我們來看看如何通過cssSelector來引用到第4種方式中提到的那個(gè)button。button代碼如下:
  <button id="J_sidebar_login" class="btn btn_big btn_submit" type="submit">登錄</button>
  cssSelector引用元素代碼如下:
  driver.findElement(By.cssSelector("button.btn.btn_big.btn_submit"))
  。這樣可以順利引用到使用了復(fù)合樣式的元素了。
  此外,cssSelector還有一些高級用法,如果熟練后可以更加方便地幫助我們定位元素,如我們可以利用^用于匹配一個(gè)前綴,$用于匹配一個(gè)后綴,*用于匹配任意字符。例如:
  匹配一個(gè)有id屬性,并且id屬性是以”id_prefix_”開頭的超鏈接元素:a[id^='id_prefix_']
  匹配一個(gè)有id屬性,并且id屬性是以”_id_sufix”結(jié)尾的超鏈接元素:a[id$='_id_sufix']
  匹配一個(gè)有id屬性,并且id屬性中包含”id_pattern”字符的超鏈接元素:a[id*='id_pattern']
  后再總結(jié)一下,各種方式在選擇的時(shí)候應(yīng)該怎么選擇:
  1. 當(dāng)頁面元素有id屬性時(shí),好盡量用id來定位。但由于現(xiàn)實(shí)項(xiàng)目中很多程序員其實(shí)寫的代碼并不規(guī)范,會缺少很多標(biāo)準(zhǔn)屬性,這時(shí)只有選擇其他定位方法。
  2. xpath很強(qiáng)悍,但定位性能不是很好,所以還是盡量少用。如果確實(shí)少數(shù)元素不好定位,可以選擇xpath或cssSelector。
  3. 當(dāng)要定位一組元素相同元素時(shí),可以考慮用tagName或name。
  4. 當(dāng)有鏈接需要定位時(shí),可以考慮linkText或partialLinkText方式。

上一頁12下一頁
軟件測試工具 | 聯(lián)系我們 | 投訴建議 | 誠聘英才 | 申請使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd