上一篇博客《Cucumber读书笔记》把整个框架概述一下。当时底层实现的Framework一笔带过,这篇博客延伸一下底层Framework层的具体实现流程。在这里讲一个比较成熟的基本的功能测试框架,核心是使用工厂模式。Product即要操作的控件。首先看一下框架的流程。
一、程序流程
通过下图我们可以基本了解整个程序的流程。我们通过ControlFactory生产我们接下来要操作的控件。每隔控件都会被识别为一个对象,对控件的操作即为该对象的方法。要识别的控件通过JS来获取,个别识别不到的,通过事先记录对应控件的ID,Xpath等信息,后来需要获取该控件时通过该信息获取控件,从而对控件进行操作。IPageAccess提供Control的的接口,PageAccess层实现对应操作的方法(webdriver,JS等)
1.1 框架基本结构
二、Business Logic Layer层
BUSIness Logic Layer层是整个流程的核心。他主要有三个功能创建Page,定位Control,创建Control。
1.创建Page的时候通过反射的方式获取创建的Page或者Popup。创建的Iwebdriver对象通过单例模式保持唯一性。
2.定位Control时,我们先通过JS来识别常出现的基本控件。剩下未识别的控件通过记录其ID,XPath等信息进行获取。
3.创建Coutrol的方法和创建Page的方法基本类似,都是通过反射的方式。通过调用对应控件的对象的方法实现对对应控件的操作。
2.1 BLL层流程
三、IPageAccess层
IPageAccess层是接口层,提供对应控件的接口给控件类继承。提供创建Coutrol时候接口类。具体接口的定义方式因项目而异,最后定义成IClickable,IMenu方便归类继承。
namespace IPageAccess { public interface IClickable : IControl { bool Click(); } } |
四、PageAccess层
PageAccess层即为具体的实现层,实现的方式是通过调用识别的对应控件的对象的相应的方法。实现的方式是webdriver,JS等。在这就不详细讨论具体的实现方式了。创建对象时,对象的参数是含有ID,Name等信息的Dictionary,对象要根据Dictionnary提供的信息定位控件,进行相应的操作。
namespace PageAccess.Portal { public class CPButton : CPBaseClickable { public CPButton(Dictionary<string, string> info) : base(info) { } protected override IWebElement Element() { IWebElement obj = null; if (Id != "") { obj = WebDriverHelper.CurrentDriver.FindElement(By.Id(Id), 10); } else { if (Name != "") { obj = WebDriverHelper.CurrentDriver.FindElement(By.Name(Name), 10); } else { if (Selector != "") { obj = WebDriverHelper.CurrentDriver.FindElement(Selector, 10); } else if (Xpath != "") { try { List<IWebElement> buttons = WebDriverHelper.CurrentDriver.FindElements(By.XPath(Xpath), 10); buttons.Remove(buttons.Find(x => x.GetAttribute("class").Contains("mce_copy"))); if (buttons.Last().Enabled && buttons.Last().Displayed) obj = buttons.Last(); else obj = buttons.First(); } catch { obj = null; } } } } if (obj == null) { throw new Exception(string.Format("Button {0} can't be found.", this.LabelRepository)); } return obj; } public override bool Click() { } #endregion } } |
4.1 PageAccess层Demo
在底层实现时,仅凭JS和selenium2是不够的,有时还要引入第三方Tool,例如AutoIT。处理一些复杂需求是同样需要引入RemoteWMI等方法实现。