[小北De编程手记] : Lesson 08 - Selenium For C# 之 PageFactory & 团队构建

  本文想跟你们分享的是Selenium对PageObject模式的支持和自动化测试团队的构建。《Selenium For C#》系列的文章写到这里已经接近尾声了,若是以前的文章你是一篇篇的读下来并动手实践的话,我相信你应该能够模拟平常工做中80%常见的手动测试用例了。请注意:个人用词是模拟用例,而不是书写自动化测试用例。一个企业级的自动化测试的构建不是单靠Selenium一种技术就能Hold住的。所谓模拟指的是只能实现自动化的某个Case,可是不能工程化的使用。在本人所接触过几家公司的自动化测试的实践中,有不少没有或着不是很合理分层和封装的自动化测试框架。Test Case中操做页面驱动的Code随处看见,没法根据人员的技术能力来分工,没法切换测试环境,只能使用单一的浏览器测试,对QA的使用门槛要求较高… …等等问题。html

本文将会介绍以下内容:git

  • PageObject设计模式介绍。
  • Selenium对PageObject模式的支持。
  • 简单的测试结构
  • 自动化测试Team成员分工
  • Demo:博客园我的首页的实现(这个是骗你的... ...)

(一)PageObject设计模式介绍

   Page Object是业界比较流行的自动化测试设计模式,可以有效的提升自动化测试的可维护性和代码的复用率。几乎全部的自动化测试驱动框架都提供了对该模式的支持(Appium ,QTP ,White等)。固然,即便你使用的驱动不支持,咱们也彻底能够编写代码来实现它。毕竟所谓设计模式不过代码的组织和协做方式而已。github

  什么是Page Object模式呢?简单的说,就是把待测试应用程序的页面封装成一个对象,暴露相关的属性和方法给使用者(具体测试用例的编写人员)。下图是针对页面的封装:编程

  能够看到,Page类提供了一个TitleText属性向用户返回页面的Title文本,还提供基本的页面操做。对于使用者来讲,他们没必要关心这个页 面上的元素是如何定位,也没必要关心内部使用了怎样的技术实现(Selenium,仍是QTP)。另外一个好处就是若是开发对页面作了元素作了必定的调 整,咱们只须要处理PageObject内部的代码实现,而不须要修改实际测试用例代码。该模式的好处还有不少,本文就不赘述了。我会在以后的框架实践相关的文章中进行描述。设计模式

(二)Selenium对PageObject模式的支持

  下面咱们一块儿来看一下,Selenium 对PageObject模式的支持。下面的代码是一个登陆页面的简单封装:浏览器

 1     public class SignInPage
 2     {
 3         public IWebDriver Driver { get; set; }
 4         public DashboardSignInPage(IWebDriver driver)
 5         {
 6             this.Driver = driver;
 7             PageFactory.InitElements(driver, this);
 8         }
 9         #region Page elements
10         [FindsBy(How = How.Id, Using = "username")]
11         protected IWebElement txtUserName;
12 
13         [FindsBy(How = How.Id, Using = "password")]
14         protected IWebElement txtPassword;
15 
16         [FindsBy(How = How.XPath, Using = ".//button[text()='Sign in']")]
17         protected IWebElement btnSignIn;
18         #endregion Page elements
19 
20         #region Action for test case
21         /// <summary>
22         /// Sign In for Dashboard
23         /// </summary>
24         /// <param name="userName">User name</param>
25         /// <param name="password">Password</param>
26         public void SignIn(string userName, string password)
27         {
28             this.txtUserName.Clear();
29             this.txtPassword.Clear();
30 
31             this.txtUserName.SendKeys(userName);
32             this.txtPassword.SendKeys(password);
33 
34             this.btnSignIn.Click();
35         }
36 
37         //Other action... ...
38         #endregion
39     }        

  上面的代码中出现的FindsBy和PageFactory正是Selenium WebDriver提供的针对PageObject模式的支持。架构

  @PageFactory类

  FageFactory提供了PageObject实例的能力,咱们能够看到它自己提供了不少的方法来构建具体的页面类的实例。它的主要做用的是将咱们用FindsBy属性标记的字段和指定的DOM元素进行映射。然后咱们能够直接使用具体属性操做DOM元素,没必要使用FindElement方法来定位。框架

1     public sealed class PageFactory
2     {
3         public static T InitElements<T>(IElementLocator locator);
4         public static T InitElements<T>(IWebDriver driver);
5         public static void InitElements(ISearchContext driver, object page);
6         public static void InitElements(object page, IElementLocator locator);
7         public static void InitElements(ISearchContext driver, object page, IPageObjectMemberDecorator decorator);
8         public static void InitElements(object page, IElementLocator locator, IPageObjectMemberDecorator decorator);
9     }

  @FindsBy属性

  FindsBy属性是用来标记程序中的元素是如何定位的。咱们可使用以前《Lesson 03 - Selenium For C# 之 元素定位》中讲到的任何一种定位方式来标记如何定位元素。利用How参数指定定位方式,这是Using参数标识具体的值。若是对如何定位元素不是很清楚,能够查看以前的文章,这里就再也不赘述了。ide

 1     // Summary:
 2     //     Provides the lookup methods for the FindsBy attribute (for using in PageObjects)
 3     public enum How
 4     {
 5         // Summary:
 6         //     Finds by OpenQA.Selenium.By.Id(System.String)
 7         Id = 0,
 8         //
 9         // Summary:
10         //     Finds by OpenQA.Selenium.By.Name(System.String)
11         Name = 1,
12         //
13         // Summary:
14         //     Finds by OpenQA.Selenium.By.TagName(System.String)
15         TagName = 2,
16         //
17         // Summary:
18         //     Finds by OpenQA.Selenium.By.ClassName(System.String)
19         ClassName = 3,
20         //
21         // Summary:
22         //     Finds by OpenQA.Selenium.By.CssSelector(System.String)
23         CssSelector = 4,
24         //
25         // Summary:
26         //     Finds by OpenQA.Selenium.By.LinkText(System.String)
27         LinkText = 5,
28         //
29         // Summary:
30         //     Finds by OpenQA.Selenium.By.PartialLinkText(System.String)
31         PartialLinkText = 6,
32         //
33         // Summary:
34         //     Finds by OpenQA.Selenium.By.XPath(System.String)
35         XPath = 7,
36         //
37         // Summary:
38         //     Finds by a custom OpenQA.Selenium.By implementation.
39         Custom = 8,
40     }

   那么最后,咱们来看一下消费者(上层的测试用例编写人员)将如何使用如何使用这个类,这个Code只是一个使用SignInPage的示例,咱们看到这里仍是在测试用例中写入了建立Driver和导航页面的代码,按照先前的架构这样也是存在问题的,这里就再也不展开了,期待我后续关于自动化框架设计的文章吧~~~:post

 1         private const string cst_DisplayName = "BaseCheck.SignIn";
 2         [Fact(DisplayName = cst_DisplayName + ".Success")]
 3         public void SignIn_Success()
 4         {
 5             var driver = new FrieFoxDriver();
 6             driver.Url = "www.xxx.com/signin";
 7 
 8             var signInPage = new SignInPage(driver);
 9             signInPage.SignIn("your name", "password");
10 
11             //省略Code... ...    
12             driver.Close();
13         }

(三)简单的测试结构

  读到这里,即便你是初学者。想必也能明白一些PageObject设计模式为什么物,这里我仍是描述一下 PageObject的意图:PageObject模式是为了封装页面元素定位,页面等待、跳转等操做页面相关的逻辑。使得使用者在没必要关心这些逻辑的情 况下,能够书写相关的测试用例。咱们回顾一下我以前在《Lesson 02 - Selenium For C# 之 核心对象》中提到的通常的企业级测试框架中的结构图:

   上图中的红线圈出来的部分就是PageObject的消费者(编写测试用例的Tester)。能够看到,下一层的开发人员能够把页面的封装成 PageObject,上层的使用者没必要关心具体的实现技术是哪种(Selenium , Appium... ...)。PageObject的消费者能够专一于Test Case的逻辑实现。

(四)自动化测试Team成员分工

  以前有不少公司或是朋友跟我探讨过如何组建自动化测试团队。无一例外都谈到了(纠结于)这些问题:须要QA Team有很强的编码能力,他们要学习各类驱动(Selenium , QTP , Appium... ...)的使用 , 了解一些JavaScript、HTML、CSS相关的知识,具备OOP思惟... ...等等等。最终的结论就是构建自动化测试对QA的人员提出了很高的要求。在我看来,若是一个QA能够具备了上述能力我想他已是一个开发人员了(这个要求不切实际)。那可不可让开发团队来完成这件事情呢?这个固然不行了,理由有N多。这里我只提两条。第一,开发团队的视角每每不是站在用户角度的,所以会极大的提高项目风险。第二,一个自动化测试构建的成功与否?合理的测试计划每每是决定性因素,可是测试计划的制定却不是开发人员所擅长的。(这里没有歧视开发的意思。嘻嘻~~本人也是开发~~~不喜勿喷)。那么,如何构建呢?这个其实也是咱们要构建测试框架,分层,使用PageObject模式的缘由了,针对上一节我画出的简单结构而言,团队中能够有以下几个角色:

@功能测试人员:

  主要是由手工测试人员和懂一些简单编程语法的测试人员组成,他们是PageObject和测试框架的直接使用者(消费者)。使用已经完成的PageObject和测试框架进行测试用例的编写,以及测试计划的制定。以我我的的经验,通常的QA简单的培训一下便可以胜任这样的工做,而他们所完成的倒是很大的一部份工做。功能测试人员专一与逻辑的测试,而不易关心技术细节。

@PageObject编写人员:

  这部分人员能够由测试团队中技术(编程技术)较高或是开发人员来担当,要求以下:

  • 熟悉相关的驱动的使用(Selenium、QTP... ....),不熟悉也不要紧,看看个人《Selenium For C#》系列哈~~~
  • 熟悉Web编程,JavaScript、HTML、CSS相关的知识。(基于B/S的测试构建,要是桌面或是手机端还要其余的知识)
  • 熟悉OOP思想,能针对页面作出合理的封装。

  所以,这部分同窗专一与提供好用的页面类,而没必要须关系纷繁复杂的业务逻辑。这部分人也是测试人员的一个职业发展方向(技术型测试)。

@测试架构师:

  这个就须要资深一些的同窗来作了,架构师的要求嘛就比较多了。他在团队中主要的任务就是构建测试的基础设施。好比页面导航的管理,提供ORM机制供测试人员使用,日志的输出,测试报告的生成,环境切换,浏览器切换,提供一些炫酷而简单的使用功能,还有就是最一些文档的输出。这样一来,测试架构师也能够关心他所须要完成的技术难题,而不关心业务和具体的页面类的实现。

 

  总结一下,有了这三种分工其实工做在不一样的层面上。各自完成所擅长的那一部分。于此同时也提供生了整个测试的可维护性。好比:页面作了修改,只须要PageObject人员去修改本身的封装。而业务逻辑出现了变动(页面不变的话),也只是须要用例编写人员修改一下本身的测试用了而已。

(五)写在最后的... ...

  原本是想作一个Demo给你们的。可是... ...过年了... ... 老妈催着回家过年,收拾行李去呀,有机会再补上吧 ... ... 今天就职性一把 哈哈 , 各位小伙伴,新年快乐!

  前面讲了分工,如今的你是哪一个级别呢?能一篇篇把个人系列文章看到这一篇的,估计多数仍是没有构建测试框架能力的小伙伴。因此,后面若是时间容许的话我会写一个关于自动化测试框架构建的系列,记得关注哦~~~

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

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

 

若是您认为这篇文章还不错或者有所收获,能够点击右下角的 【推荐】按钮,由于你的支持是我继续写做,分享的最大动力!
做者:小北@North
来源:http://www.cnblogs.com/NorthAlan
声明:本博客原创文字只表明本人工做中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未受权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文链接。
相关文章
相关标签/搜索