[小北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
声明:本博客原创文字只表明本人工做中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未受权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文链接。
相关文章
相关标签/搜索