当时底层实现的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
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
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等方法实现。