[小北De編程手記] : Lesson 03 - Selenium For C# 之 元素定位

  不管哪種自動化測試的驅動框架(基於B/S,桌面應用,仍是手機App)。都應當具備一套優秀的元素定位技術。一般的自動化測試流程也能夠簡單的歸結爲是一個從被測試程序中識別或是定位元素以及執行操做和驗證元素的過程。這一篇咱們就開始給你們介紹一下Selenium中是如何定位DOM元素的。本文將會介紹以下內容:css

  • Selenium DOM 主要的定位方式。
  • Selenium 如何擴展元素定位方式。
  • 輔助瀏覽器工具

(一)Selenium DOM主要定位方式

  上一篇中,咱們介紹了WebDriver 和 WebElement兩個類型。他們都具備方法FindElement和FindElements。 這即是Selenium WebDriver的API提供給咱們的元素定位方式。IWebDriver要求同時實現接口ISearchContext,元素查找的方法即是在這個接口中定義的:html

1 public interface IWebDriver : ISearchContext, IDisposable
2 {
3     //省略部分Code... ...       
4 }
 1 namespace OpenQA.Selenium
 2 {
 3     // Summary:
 4     //     Defines the interface used to search for elements.
 5     public interface ISearchContext
 6     {
 7         IWebElement FindElement(By by);
 8 
 9         ReadOnlyCollection<IWebElement> FindElements(By by);
10     }
11 }

 他們都會接受一個By類型的參數。該類型的官網定義以下所示,Selenium主要提供瞭如下幾種方式定位元素:git

  • ID : 根據DOM元素的ID屬性定位。
  • Name : 根據DOM元素的Name屬性定位。
  • ClassName : 根據DOM元素的Class屬性定位。
  • TagName : 根據DOM元素的TagName定位。
  • LinkText : 根據DOM元素(link)的文本內容定位。
  • PartialLinkText : 根據DOM元素(link)的部分文本內容定位。
  • CssSelector:根據CSS 選擇器定位元素。
  • XPath:使用XPath定位元素。

  

元素定位的調用方式以下:github

 1 IWebDriver driver = new FirefoxDriver ();
 2 IWebElement element;
 3 
 4 element = driver.FindElement(By.Id("ObjectID"));
 5 element = driver.FindElement(By.Name("ObjectName"));
 6 element = driver.FindElement(By.ClassName("ObjectClassName"));
 7 element = driver.FindElement(By.TagName("ObjectTagText"));
 8 element = driver.FindElement(By.LinkText("ObjectLinkText"));
 9 element = driver.FindElement(By.PartialLinkText( "ObjectPartialLinkText"));
10 
11 // Use css selector.
12 element = driver.FindElement(By.CssSelector( "CssSelector For Object"));
13 // Use xPath.
14 element = driver.FindElement(By.XPath("XPath For Object"));

  下面簡單的介紹一下DOM元素的ID,Name,ClassName... ...XPath,CssSelector都是些什麼鬼? 固然,若是你是一個已經很熟悉這些概念的小夥伴就能夠直接忽略這部份內容。關於DOM元素的基本概念和知識這裏我就不詳細的描述了,有興趣的小夥伴能夠到這個連接學習一下:http://www.runoob.com/html/html-tutorial.html。編程

  簡單的說基本的HTML元素(DOM元素)構成了網頁的內容,每一個元素都是以一個個DOM標籤的形式表現出來的。下面是一個網頁標籤的結構。我標出了ID,TagName,ClassName,Name所對應了位置。瀏覽器

  結合以前介紹的By Class提供的靜態方法。咱們就能夠定位到對應的HTML元素的位置。說到這裏,不少資料或是書本都會有這樣的描述:「編碼中,使用ID,Name,Class屬性是定位元素的首選方法」。沒錯這些元素定位簡單直接,並且理論上的執行效率較快。可是(請注意,我說了可是~~~),現實的狀況是開發人員可能根本就沒有爲元素定義這些屬性,或者實際的應用ID是自動隨機生成的,Name和ClassName又不能準確的惟必定位,此刻咱們就須要其餘的方式來定位元素。這也是XPath和Css選擇器的做用了,實際的工做中,這兩種定位方式應當是伴隨你的主要方式,so ... ... 好好了解一下仍是頗有必要的。關於XPath和Css選擇器的語法已經超出了咱們要討論的問題,想了解的小夥伴能夠網上找一下相關的資料,這裏我就很少說了。下面咱們能夠看一下定位博客園首頁導航的XPath:網絡

1 var divMain = driver.FindElement(By.Id("main"));
2 var lnkHome = driver.FindElement(By.XPath(".//ul[@class='post_nav_block']/li[1]/a"));
3 var lnkEssence = driver.FindElement(By.XPath(".//ul[@class='post_nav_block']/li[2]/a"));
4 var lnkCandidate = driver.FindElement(By.XPath(".//ul[@class='post_nav_block']/li[3]/a"));
5 var lnkNews = driver.FindElement(By.XPath(".//ul[@class='post_nav_block']/li[4]/a"));

關於獲取超連接元素的兩個方法By.LinkText和By.PartialLinkText,簡單明瞭,在此我就很少作介紹了。架構

(二)Selenium 如何擴展元素定位的方式

除了基本的定位方式以外,若是咱們想擁有自定義的定位應該如何處理呢?好比,咱們的測試過程當中,咱們想一次性獲取到全部CSS樣式是.btn的input標籤應當如何處理?框架

  Selenium自己的底層驅動是基於JS的,同時也爲咱們上層的使用者(測試CASE編寫者或測試框架開發者)爲提供了能夠的執行自定義JS,並返回數據的方法。回顧一下上文中將到的核心對象WebDriver,都是繼承自RemoteWebDriver。而RemoteWebDriver實現了IJavaScriptExecutor接口,該接口定義了執行JS的行爲:函數

 1 namespace OpenQA.Selenium
 2 {
 3     // Summary:
 4     //     Defines the interface through which the user can execute JavaScript.
 5     public interface IJavaScriptExecutor
 6     { 
7
object ExecuteAsyncScript(string script, params object[] args); 8 object ExecuteScript(string script, params object[] args); 9 } 10 }

  所以,咱們能夠利用以下方式來執行咱們自定義的JS,略懂JavaScript的同窗看到這裏,貌似應該明白了什麼。沒錯,你能夠自由的翱翔了(定義任何你想要的定位邏輯,不只僅是定位元素)。固然,這個只是Selenium提供的接口,真正的使用和企業級的封裝有機會的話我會開一個新的系列爲你們介紹,本節先介紹到這裏。

1 IJavaScriptExecutor jsExecutor = driver as IJavaScriptExecutor ;
2 jsExecutor.ExecuteScript("return $('#elementID')");

(三)瀏覽器輔助工具

編程就像習武,功力深厚當然好,但總要有合手的兵器。接下來,爲你們推薦一下元素定位可能會用到的工具:

若是你用的是Firefox瀏覽器,建議你下載Firebug和FirePath:

  • Firebug擁有不少功能(元素定位,腳本調試,網絡監控 等等),能夠幫你輕鬆的定位元素和觀察DOM結構。
  • FirePath理論上能夠用來生成元素的XPath或是驗證XPath的定位效果。(雖然工具能夠生成XPath也不要期望靠他生成,仍是要好好學習XPath的... ... 由於,工具生成的結果每每不是你想要的)。

若是你用的是Chrome或是IE瀏覽器,他們都有內置的開發者工具。

關於XPath的驗證步驟,請參考下圖(輸入Xpath>點擊Eval>查看定位到的元素):

(四)Demo

  說了這麼多,又到了作Demo時候了。so... 一樣作了個簡單的Demo供你們參考。Code上傳到Github地址是:https://github.com/DemoCnblogs/Selenium,本節的Demo是用來驗證了博客園首頁的導航欄內的文字是否正確,使用了幾種方式獲取DOM元素,代碼以下:

 1 using OpenQA.Selenium;
 2 using OpenQA.Selenium.Firefox;
 3 using System.Collections.Generic;
 4 using Xunit;
 5 using Xunit.Abstractions;
 6 
 7 namespace Demo.SeleniumTest
 8 {
 9     public class Lesson03_FindElement
10     {
11         /// <summary>
12         /// 輸出對象
13         /// </summary>
14         private readonly ITestOutputHelper _output;
15         /// <summary>
16         /// 構造函數,初始化輸出對象
17         /// </summary>
18         /// <param name="output">注入輸出對象</param>
19         public Lesson03_FindElement(ITestOutputHelper output)
20         {
21             this._output = output;
22         }
23 
24         /// <summary>
25         /// demo1 : 獲取元素
26         /// </summary>
27         [Fact(DisplayName = "Cnblogs.CheckNavBar.Demo1")]
28         public void CheckNavBar_GetElement()
29         {
30             _output.WriteLine("Step 01 : 啓動瀏覽器並打開博客園首頁。");
31             IWebDriver driver = new FirefoxDriver();
32             driver.Url = "http://www.cnblogs.com";
33 
34             _output.WriteLine("Step 02 : 尋找須要檢查的頁面元素。");
35             var divMain = driver.FindElement(By.Id("main"));
36             var lnkHome = driver.FindElement(By.XPath(".//ul[@class='post_nav_block']/li[1]/a"));
37             var lnkEssence = driver.FindElement(By.XPath(".//ul[@class='post_nav_block']/li[2]/a"));
38             var lnkCandidate = driver.FindElement(By.XPath(".//ul[@class='post_nav_block']/li[3]/a"));
39             var lnkNews = driver.FindElement(By.XPath(".//ul[@class='post_nav_block']/li[4]/a"));
40 
41             _output.WriteLine("Step 03 : 檢查導航條文字信息。");
42             Assert.Equal<string>("首頁", lnkHome.Text);
43             Assert.Equal<string>("精華", lnkEssence.Text);
44             Assert.Equal<string>("候選", lnkCandidate.Text);
45             Assert.Equal<string>("新聞", lnkNews.Text);
46 
47             _output.WriteLine("Step 04 : 關閉瀏覽器。");
48             driver.Close();
49         }
50 
51 
52         [Fact(DisplayName = "Cnblogs.CheckNavBar.Demo2")]
53         public void CheckNavBar_GetElements()
54         {
55             _output.WriteLine("Step 00 : 準備測試數據。");
56             var testDatas = new List<string>() { "首頁", "精華", "候選", "新聞" };      //準備測試數據
57 
58             _output.WriteLine("Step 01 : 啓動瀏覽器並打開博客園首頁。");
59             IWebDriver driver = new FirefoxDriver();
60             driver.Url = "http://www.cnblogs.com";
61 
62             _output.WriteLine("Step 02 : 尋找須要檢查的頁面元素。");
63             var divMain = driver.FindElement(By.Id("main"));
64             var lnkNavList = driver.FindElements(By.XPath(".//ul[@class='post_nav_block']/li[1]/a"));
65 
66             _output.WriteLine("Step 03 : 檢查導航條文字信息。");
67             for (var i = 0; i < lnkNavList.Count; i++)
68             {
69                 Assert.Equal<string>(testDatas[i], lnkNavList[i].Text);
70             }
71             _output.WriteLine("Step 04 : 關閉瀏覽器。");
72             driver.Close();
73         }
74     }
75 }

 

總結:本文主要介紹瞭如下幾點內容。

  • Selenium元素定位方式(ID,Name,ClassName,TagName,XPath,Css選擇器等等)。
  • 如何擴展Selenium,並自定義定位方式
  • 推薦了一些輔助工具

關於《Selenium For C#》 系列,我計劃給你們逐一介紹一些Selenium Driver的基礎知識和框架的擴展點。 固然,以後會有更多關於測試框架構以及軟件構建方面的文章。願我主保佑我有時間作完這件事情... ...

《Selenium For C#》的相關文章:Click here.

說明:Demo地址:https://github.com/DemoCnblogs/Selenium

若是您認爲這篇文章還不錯或者有所收穫,能夠點擊右下角的 【推薦】按鈕,由於你的支持是我繼續寫做,分享的最大動力!
做者:小北@North
來源:http://www.cnblogs.com/NorthAlan
聲明:本博客原創文字只表明本人工做中在某一時間內總結的觀點或結論,與本人所在單位沒有直接利益關係。非商業,未受權,貼子請以現狀保留,轉載時必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
相關文章
相關標籤/搜索