您的位置:軟件測試 > 開源軟件測試 > 開源功能測試工具 > Selenium
全球化測試中利用Selenium定位Web元素難點(diǎn)解析
作者:網(wǎng)絡(luò)轉(zhuǎn)載 發(fā)布時間:[ 2016/6/22 11:06:11 ] 推薦標(biāo)簽:功能測試工具 Selenium

  清單 3. WebDriver 特有的定位方式
  //by Partial Link Text
  WebElement element = driver.findElement(By.partialLinkText("Con")); (10)//in WebDriver
  //by Tag Name
  WebElement element = driver.findElement(By.tagName("p")); (09)/in WebDriver
  //by Class
  List<WebElement> WEs = driver.findElements(By.className("required"));(4&5)//in WebDriver
  CSS 選擇器
  CSS 選擇器是由關(guān)系符分開的一個或多個簡單選擇器序列組成的選擇器序列鏈,后一個簡單選擇器序列的后面還可以添加一個偽元素。簡單選擇器序列是單純由簡單選擇器組成的選擇器鏈,它通常由一個標(biāo)簽選擇器或者通配符選擇器開頭,之后序列中不允許再出現(xiàn)其他標(biāo)簽選擇器和通配符選擇器。簡單選擇器可以是 ID 選擇器、類選擇器、類型(標(biāo)簽)選擇器、通配符選擇器、屬性選擇器和偽類選擇器。關(guān)系符可以是空格、大于號、加號和波浪符。關(guān)系符和簡單選擇器周圍允許出現(xiàn)空白(空格符、tab 符、換行符、回車符、換頁符)。多個 CSS 選擇器還可以用逗號拼接為一個組合選擇器,滿足任意其中一個選擇器的元素都會被該組合選擇器選中,逗號的前后允許出現(xiàn)空白。某些選擇器支持命名空間前綴,命名空間前綴的聲明機(jī)制應(yīng)該由使用選擇器的語言指定,如果使用選擇器的語言沒有指定命名空間前綴聲明機(jī)制,那么沒有前綴聲明。在 CSS 中,命名空間通過 @namespace 規(guī)則聲明。
  清單 4. HTML 示例 2
(01)<html>
(02) <body>
(03) <form id="loginForm" name="loginFrom">
(04) <input class="required" name="username" type="text" />
(05) <input class="required passfield" name="password" type="password" />
(06) <input name="continue" type="submit" value="Login" />
(07) </form>
(08) <p class="ask">Are you sure you want to do this?</p>
(09) <a href="continue.html">Continue</a>
(10) <a href="cancel.html" hreflang=en-US>Cancel</a>
(11) <div>
(12) <ul id="structure">
(13) <li>Cat</li>
(14) <li>Dog</li>
(15) <p>fish</p>
(16) <li>Car</li>
(17) <li>Goat</li>
(18) </ul>
(19) </div>
(20)</body>
(21)<html>
  簡單選擇器
  ID、類、類型(標(biāo)簽)、通配符選擇器

  文檔中可能包含被聲明為 ID 類型的屬性,ID 類型的屬性的特殊之處在于一份文檔中的任意兩個元素不會有相同的 ID 值。無論文檔語言是什么,ID 類型的屬性可以用來地標(biāo)識它所在的元素。ID 選擇器由數(shù)目符號 (U+0023, #) 和合法的 ID 值組成,ID 選擇器指代具有與定位器匹配的 ID 值的文檔元素,如清單 5 所示 (行末括號中的數(shù)字顯示當(dāng)前行定位器將定位到清單 4HTML 文檔中的第幾行元素)。當(dāng)在 HTML 中表示 class 屬性時通常將句點(diǎn)符號 ( U+002E) 作為~=的替代符號,因此在 HTML 中 div.value 與 div[class~=value] 具有相同的意義,均定位到 class 為 value 的 div 元素。需要特別注意的是形如 p.pastoral.marine{color:green} 的選擇器將匹配到 class 屬性既包含 pastoral 又包含 marine 且二者用空格分隔的 p 標(biāo)簽,例如匹配到 class="pastoral blue aqua marine"而匹配不到 class="pastoral blue"。類型選擇器中的類型是元素類型的名稱,類型選擇器指代文檔樹中具有相同類型的元素,如清單 5 所示。通配符選擇器使用星號 (* U+002A) 指代任意元素類型的合法名稱。如果星號表示的通配符選擇器不是簡單選擇器序列的組件或者它的后面緊跟著一個偽元素,那么可以省略該星號而暗指含有一個通配符選擇器,然而有些情況下不推薦省略,比如 div *:first-child 比 div :first-child 更易讀,不至于和 div:first-child 混淆。另外類型選擇器和通配符選擇器都支持命名空間前綴,命名空間前綴使用豎線 (U+007C, |) 與選擇器分隔,可以為空也可以為通配符星號。在沒有命名空間前綴和分隔符的情況下,若沒有聲明命名空間則表示任意命名空間,若已聲明默認(rèn)命名空間則表示默認(rèn)命名空間。
  屬性選擇器
  屬性選擇器通過對元素屬性進(jìn)行匹配來進(jìn)行選擇和定位。屬性選擇器又分為存在和值選擇器以及子串匹配屬性選擇器。前者又分為四種:[att] 指代具有 att 屬性的元素,而不論屬性的值是什么;[att=val] 指代屬性的值為 val 的元素;[att~=val] 指代這樣的元素,其屬性值由空格分隔的多個值組成,其中一個值和 val 完全匹配;[att|=val] 指代屬性值為 val 或者前綴為“val-”。子串匹配屬性選擇器提供了匹配屬性值子串的能力,比如 [att^=val] 指代屬性值前綴為 val 的元素;[att$=val] 指代屬性值后綴為 val 的元素;[att*=val] 指代屬性值中含有 val 字符串的元素。在這兩種屬性選擇器中屬性值必須為 CSS 合法字符,大小寫敏感度與具體的文檔語言有關(guān)。詳細(xì)示例如清單 5 所示。屬性選擇器也支持命名空間前綴,與類型和通配符選擇器不同的是對于沒有命名空間前綴或者命名空間前綴為空的屬性選擇器,其只匹配到?jīng)]有命名空間前綴的元素。
  偽類選擇器
  偽類選擇器可以說是定位 Web 元素的后救命稻草,它允許使用文檔樹以外的信息選取元素,這能完成很多其它選擇器不能完成的工作。偽類總是由一個前面加了冒號的偽類名組成,偽類可以存在于所有的選擇器序列中,它可以位于主選擇器或者通配符選擇器之后。偽類區(qū)分大小寫,有些偽類是互斥的,有些偽類則可以同時使用。偽類可以是動態(tài)的,某種意義上說隨著用戶與文檔的交互一個偽類可以獲得或者失去對一個元素的匹配。偽類從實(shí)現(xiàn)方式可分為動態(tài)偽類(如互斥的:link 和:visited, :hover, :active, :focus),目的偽類(:target),語言偽類(:lang),元素狀態(tài)偽類(:enabled, :disabled, :checked, :indeterminate),結(jié)構(gòu)偽類,內(nèi)含偽類和否定偽類,若以定位元素為目的的話這里只有結(jié)構(gòu)偽類和內(nèi)含偽類才對我們有用,其他偽類主要應(yīng)用在元素樣式渲染領(lǐng)域特別是隨著用戶操作自動改變元素樣式的場景。
  結(jié)構(gòu)偽類可以基于文檔樹的結(jié)構(gòu)定位元素,其中標(biāo)準(zhǔn)文本和其它非節(jié)點(diǎn)元素沒有被算進(jìn)父節(jié)點(diǎn)的子節(jié)點(diǎn)列表中,子節(jié)點(diǎn)的位置索引從 1 開始計(jì)算。結(jié)構(gòu)偽類包含十二種::root 偽類指代文檔的根節(jié)點(diǎn),在 Html4 中通常指 HTML 元素;:nth-child(an+b), n>=0 偽類指代在第 an+b 個孩子節(jié)點(diǎn),即其之前有 an+b-1 個兄弟節(jié)點(diǎn)的元素,舉例來說:nth-child(2n) 指代第偶數(shù)個孩子節(jié)點(diǎn),:nth-child(2n+1) 指代第奇數(shù)個孩子節(jié)點(diǎn),:nth-child(4) 指代第 4 個元素孩子節(jié)點(diǎn);tag:nth-of-type(an+b), n>=0 指代第 an+b 個類型為 tag 的孩子節(jié)點(diǎn),非 tag 類型的節(jié)點(diǎn)不參與計(jì)數(shù);:nth-last-child(an+b),n>=0 偽類指代從后往前數(shù)第 an+b 個孩子節(jié)點(diǎn),即其后有 an+b-1 個兄弟節(jié)點(diǎn);:nth-last-of-type 指代從后往前數(shù)第 an+b 個類型為 tag 的節(jié)點(diǎn);:first-child,:last-child,:first-of-type,:last-of-type 分別是上述四種偽類的特例,指代第一個或者后一個孩子節(jié)點(diǎn);:only-child 偽類指代沒有兄弟節(jié)點(diǎn)的孩子節(jié)點(diǎn);:only-of-type 偽類指代沒有相同類型的兄弟節(jié)點(diǎn)的孩子節(jié)點(diǎn);:empty 偽類指代沒有孩子節(jié)點(diǎn)的節(jié)點(diǎn)。詳細(xì)示例見清單 5。
  內(nèi)含偽類(:contains())通過元素上包含的文本來定位元素,由于在翻譯驗(yàn)證性測試的特殊性,該定位方法需配合英文文本與本地化翻譯文本的映射才能有效使用。
  清單 5. CSS 簡單選擇器
//by ID selector
#loginForm(03)
//by Class selector
.ask(08)
/by Type selector
p.ask(08)
//by Universal selector
*|*(all)
//by attribute presence and value selector
input[value](06)
input[name="continue"](06)
input[class~="required"][name="password"](05)
a[hreflang|="en"](10)
//by substring matching attribute selector
a[href^="cancel"](10)
a[name$="name"](04)
a[name*="pass"](05)
//by structural pseudo-classes
ul#structure li:nth-child(4)//只有當(dāng)?shù)谒膫子元素是 li 時才可成功定位到 (16)
ul#structure li:nth-of-type(4)(17)
ul#structure nth-last-child(3)(15)
ul#structure li:nth-last-of-type(3)(14)
//by contains pseudo-class
li:contains("Cat")(13)
  關(guān)系選擇器
  由于編碼不規(guī)范等問題,僅僅通過簡單選擇器有時候并不能定位到我們預(yù)期得到的元素,這時我們還可以通過元素間的代繼關(guān)系,首先定位到目標(biāo)元素的祖先或父親或兄弟節(jié)點(diǎn),然后借助關(guān)系選擇器進(jìn)行定位。常見的關(guān)系選擇器有后代選擇器、子選擇器和兄弟選擇器三種:后代選擇器使用空格分隔兩個簡單選擇器以代表二者具有祖先、后代關(guān)系,形如“A B”的后代選擇器代表目標(biāo)元素 B 為 A 的任意后代元素;子選擇器使用大于號分隔兩個簡單選擇器以代表其父子關(guān)系,形如“A B”的子選擇器代表目標(biāo)元素 B 為 A 的子元素;兄弟選擇器分為兩種,相鄰兄弟選擇器和一般兄弟選擇器。相鄰兄弟選擇器使用加號分隔兩個簡單選擇器以代表二者具有相同的父元素且位置臨近,形如“A + B”的兄弟選擇器代表目標(biāo)元素 B 為緊隨 A 后面的兄弟元素。一般兄弟選擇器使用波浪號分隔兩個簡單選擇器以代表后者與前者具有相同的父元素,而并不要求這兩個元素位置臨近。如清單 6 所示:
  清單 6. 關(guān)系選擇器
  //by Descendant combinator
  div p(15)
  //by Child combinators
  body > p(08)
  //by General sibling combinator
  form + p 或者 div ~ p(08)
  技巧&難點(diǎn)拾遺
  由上文可見,在編寫翻譯驗(yàn)證性測試自動化腳本的時候一般這樣依次選取定位元素的方法:有 ID 或者 name 屬性直接用其定位。對于無 ID 或 name 的情況,屬性組合能定位的可采用 CSS 屬性選擇器,文檔結(jié)構(gòu)能定位的可采用 CSS 結(jié)構(gòu)偽類選擇器;對于 CSS 屬性選擇器和結(jié)構(gòu)偽類仍不能解決的情況,如果相關(guān)元素可以精確定位的話還可以借助關(guān)系選擇器進(jìn)行定位。后,雖然翻譯驗(yàn)證性測試自動化腳本“一次編寫,多個語言環(huán)境執(zhí)行”的特點(diǎn)限制了 CSS 內(nèi)含偽類的開箱即用,但是如果能借助外部程序?qū)崿F(xiàn)用戶界面中需要翻譯的英文字符串與翻譯好的本地化字符串之間的映射的話,可以直接在英文環(huán)境下編寫自動化腳本時將英文字符串作為內(nèi)含偽類的參數(shù)定位元素,當(dāng)在其他本地化環(huán)境下運(yùn)行腳本時將內(nèi)含偽類的參數(shù)替換為本地化字符串即可。
  此外,有時會發(fā)現(xiàn)明明定位器語法正確但是仍然無法獲得元素,這可能是由于 iframe 存在的緣故。對于 iframe 里的元素,要先顯示進(jìn)入那個 iframe 之后才可定位(比如在 selenium IDE 里要先 selectFrame 進(jìn)入那個 iframe,參數(shù)為 iframe 的名字)。
  后,實(shí)際應(yīng)用中一般無需完全掌握 XPath 或 CSS 選擇器的語法,利用一些諸如 XPath Checker 和 Firebug/FirePath 的瀏覽器插件可以方便地獲取 XPath/CSS Path 并驗(yàn)證其正確性(一般在插件控制臺中可以使用$$() 驗(yàn)證 CSS Path,利用 $x() 驗(yàn)證 XPath)。
  總結(jié)
  綜上所述,由于 Web 技術(shù)的發(fā)展及翻譯驗(yàn)證性自動化測試需求的特殊性,在編寫 Selenium 自動化腳本定位元素時存在著一些難點(diǎn),本文通過實(shí)例詳述了各種定位尤其是 CSS Path 定位的方法,并針對上述難點(diǎn)分享了一些個人見解,希望對大家有所啟發(fā)。

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