上回说到,一时无聊用类把自定义的对象来了个大封装。起初只是为了方便写代码,感觉有个小规范好一点点。但是旁边的峰锅锅说,既然你都写成了类,为什么不顺便做一个由excel驱动的框架呢?
这个excel的框架,说白了,就是完全抛开QTP(现在好像叫uft)只需在excel中写出事件的始末,就能在QTP中执行相关的操作。
恩恩,就像下面这个excel似的。(非常感谢峰锅锅提供他们公司以前的这个文件)个人感觉比frameworkManager 轻量级,也更直观。这个excel定义了在登录界面输入用户名,密码,并点击确定这一系列事件
第一列,对象描述,就相当于注释。然后第2-9列,都是一级一级的描述当前的对象。最后是描述所做的事件和传入的值
比如第一行,就是描述一个在登录界面的用户名输入框中执行set动作,传入的值是"yzh"。层次结构是User Login(窗口)-User:(文本框)
基本需求已经明白了。现在就是实现的问题了。
一句话总结这个框架:先一步步找到对象(通过excel中传入的对象的类型和属性),然后执行此对象的方法。
至于对象是怎么找到的,为什么下面的代码用GetChildXXX()就能找到对象,那是因为这些对象我都用类封装了。下面开始贴代码。
首先,准备一个main函数。这个函数的功能就是通过解析excel,把里面的文字取出来,然后通过文字new出希望得到的对象(这个就相当于执行switch case),再执行它定义了的操作。
Dim curText '全局变量 最后一个文本信息
Dim curRow '全局变量 当前运行到的行
Dim couldDo '全局变量,判断下一行是否执行,这个是用来做if功能的。
couldDo=1 '初始化对象
Function Main(inputSheet,rowStart,rowEnd)'传入的表,开始执行的行,结束执行的行
Dim objAttr1,objAttr2,objAttr3,objAttr4 '定义了4个对象,比如javawindow
Dim objValue1,objValue2,objValue3,objValue4 '定义了相对应的4个属性,比如“password:”
Dim curObj '这个是当前的对象
Dim allRowCount
allRowCount=inputSheet.AllRowCount '传入的表,获取这个表的行列
If rowStart=0 Then
rowStart=1 '这句话是说,如果传入了0,则从第一行执行,也就是说,如果我在main中传入0,0。那么,就会执行excel所有的行
End If
If rowEnd=0 Then
rowEnd=allRowCount
End If
print "表格行数"&allRowCount
For i = rowStart To rowEnd Step 1
curRow=rowStartTemp
print "第"&i&"句动作执行"
objAttr1=inputSheet.GetRowColData(i,2) '取excel中某行某列的值,i即是循环取这个excel直到所有需要的行
objValue1=inputSheet.GetRowColData(i,3)
print "对象一:"&objAttr1
objAttr2=inputSheet.GetRowColData(i,4)
objValue2=inputSheet.GetRowColData(i,5)
print "对象二:"&objAttr2
objAttr3=inputSheet.GetRowColData(i,6)
objValue3=inputSheet.GetRowColData(i,7)
print "对象三:"&objAttr3
objAttr4=inputSheet.GetRowColData(i,8)
objValue4=inputSheet.GetRowColData(i,9)
print "对象四:"&objAttr4
actionText=inputSheet.GetRowColData(i,10)
actionValue=inputSheet.GetRowColData(i,11)
'执行完这一步之后,我们就把excel中某一行的所有文本都取出来了。
'下面的代码写的很菜,但是非常的直观。
If objAttr1<>"" Then
set curObj=NewObj(objAttr1,objValue1) '如果第一个对象文本不是空的,就创建这个对象。
End If
If objAttr2<>"" Then
set curObj=GetNewObj(curObj,objAttr2,objValue2) '如果第二个对象的文本不是空的,就找到它的子对象,并用来代替当前对象
print "获取对象2 "&objAttr2
End If
If objAttr3<>"" Then
set curObj=GetNewObj(curObj,objAttr3,objValue3)
print "获取对象3 "&objAttr3
End If
If objAttr4<>"" Then
set curObj=GetNewObj(curObj,objAttr4,objValue4)
print "获取对象4 "&objAttr4
End If
'然后,就是一步步找,如果不是空的,就找到这个子对象,然后代替当前的对象。多亏了vbs是弱类型的啊。真开心
'这里有些难理解,其实是为了方便以后做if功能。在excel中做if功能?是不是很有趣呀。我们先不管这个
If couldDo=1 Then
DoAction curObj,actionText,actionValue '先不管哈,这句就是,如果最终的对象找到了。就可以执行它的事件了,传入事件的名字和事件的主体对象。用DoAction这个方法来执行
ElseIf couldDo=0 Then
couldDo=1
End If
print "第"&i&"句动作执行结束"
print " "
Next
End Function
好了,下面就是三个方法,
DoAction '通过传入的事件名,和事件附加的值,执行事件,这是整个框架的核心。
NewObj '创建一个初始的对象(需要传入对象类型和对象的某个属性)
GetNewObj '从某个对象中找到子对象(需要传入子对象的类型和子对象的某个属性值)下面是DoAction的一个小事例,传入一个对象(obj),如果是set,就执行相应的事件,如果是click。就执行另外的事件。如果是。。。。。只要你喜欢,能写个几百个事件。简直太简单了,简直太没技术含量了。简直太不符合重构的思想了。。。如果你不爽,可以想办法参考frameworkManager重构一下。
Function DoAction(obj,actionText,actionValue)
If actionText="set" Then
If obj.itself.Exist(2) Then
print "执行set"&actionValue&"列"
obj.itself.set DataTable(actionValue, dtLocalSheet)
End If
ElseIf actionText="click" Then
If obj.itself.Exist(2) Then
print "执行click"
obj.ClickButton
End If
End if
End Function
然后就是NewObj的代码。和DoAction一样,就是一大堆的if。然后new出相应的对象。如果传入的是JavaWindow,就new一个javawindow对象。否则就…………值得注意的是,ClassJavaWindow是我自定义的类,这个在上一篇文章中讲过了。都不好意思贴出来,因为太没技术了,太不符合程序员的作风了。。。
Function NewObj(attr,value)
If attr="JavaWindow" Then
Set ClassJavaWindowObj =new ClassJavaWindow
ClassJavaWindowObj.SetJavaWindow(value)
Set NewObj= ClassJavaWindowObj
print "已经创建 ClassJavaWindow"
ElseIf attr="JavaDialog" Then
Set ClassJavaDialogObj =new ClassJavaDialog
ClassJavaDialogObj.SetJavaDialog null,value
Set NewObj= ClassJavaDialogObj
print "已经创建 ClassJavaDialog"
End If
End Function
最后,就是找子对象的函数,思想就是和上面的一模一样的。就是通过传入的文本,new出相应的子对象返回。像GetChildXXX之类的方法,是在类里面就定义好了的。这个前面已经说过了。
Function GetNewObj(obj,attr,value)
If attr="JavaEdit" Then
set GetNewObj=obj.GetChildEdit(value)
'print "GetChildEdit"
ElseIf attr="JavaButton" Then
set GetNewObj=obj.GetChildJavaButton(value)
'print "GetChildJavaButton"
ElseIf attr="JavaDialog" Then
set GetNewObj=obj.GetChildJavaDialog(value)
'print "GetChildJavaDialog"
ElseIf attr="JavaStaticText" Then
set GetNewObj=obj.GetChildJavaStaticText(value)
ElseIf attr="JavaTable" Then
set GetNewObj=obj.GetChildJavaTable(value)
ElseIf attr="JavaList" Then
set GetNewObj=obj.GetChildJavaList(value)
ElseIf attr="JavaMenu" Then
set GetNewObj=obj.GetChildJavaMenu(value)
End If
End Function
然后,要注意的一个问题就是,类函数取名字的问题,一定要切记,不管是什么类,只要是找类中的相同的子对象,都一定要取相同的函数名字,否则就是在给自己找不痛快。比如要找子按钮,无论是在哪个类中,函数名都必须是GetChildJavaButton(value)
最后 上一个很有代表性的类JavaWindow。里面有各种找子控件的方法。写的很差劲。 但是因为差劲,所以直观。其它的类几乎就是它的翻版。框架打完!
rem 表示所有的javaWindow类
Class ClassJavaWindow
'定义内部可能出现的控件
private m_JavaWindow
Private m_ChildEdit
Private m_ChildJavaButton
Private m_ChildJavaStaticText
Private m_ChildJavaMenu
Private m_ChildJavaDialog
Private m_ChildJavaTable
Private m_ChildJavaList
rem 根据title定义窗口实例,每个方法都有一个SetXXXX的函数。通过这个,我们就能创建出一个完整的对象。
Public function SetJavaWindow(title)
set m_JavaWindow=JavaWindow("title:="&title)
End function
rem 只读属性:返回自身
Public Property Get ItSelf
set ItSelf = m_JavaWindow
End Property
rem 方法,获取该窗口中的一个edit
public function GetChildEdit(attachedtext)
Set m_ChildEdit=new ClassJavaEdit
m_ChildEdit.SetJavaEdit m_JavaWindow,attachedtext
set GetChildEdit=m_ChildEdit
End function
rem 方法,获取该窗口中的一个JavaList
public function GetChildJavaList(attachedtext)
Set m_ChildJavaList=new ClassJavaList
m_ChildJavaList.SetJavaList m_JavaWindow,attachedtext
set GetChildJavaList=m_ChildJavaList
End function
rem 方法,获取该窗口中的一个JavaTable
public function GetChildJavaTable(tagName)
Set m_ChildJavaTable=new ClassJavaTable
m_ChildJavaTable.SetJavaTable m_JavaWindow,tagName
set GetChildJavaTable=m_ChildJavaTable
End function
'
rem 方法,获取该窗口中的一个JavaDialog
public function GetChildJavaDialog(title)
Set m_ChildJavaDialog=new ClassJavaDialog
m_ChildJavaDialog.SetJavaDialog m_JavaWindow,title
set GetChildJavaDialog=m_ChildJavaDialog
End function
rem 方法,获取该窗口中的一个Button
public function GetChildJavaButton(attachedtext)
Set m_ChildJavaButton=new ClassJavaButton
m_ChildJavaButton.SetJavaButton m_JavaWindow,attachedtext
set GetChildJavaButton=m_ChildJavaButton
End function
rem 方法,获取该窗口中的一个javastatictext
public function GetChildJavaStaticText(label)
Set m_ChildJavaStaticText=new ClassJavaStaticText
m_ChildJavaStaticText.SetJavaStaticText m_JavaWindow,label
set GetChildJavaStaticText=m_ChildJavaStaticText
End function
rem 方法,获取该窗口中的一个JavaMenu
public function GetChildJavaMenu(label)
Set m_ChildJavaMenu=new ClassJavaMenu
m_ChildJavaMenu.SetJavaMenu m_JavaWindow,label
set GetChildJavaMenu=m_ChildJavaMenu
End function
End Class
现在这个框架已经能完成80%的自动化测试,即使不懂代码的测试员,也能写出基本的自动化脚本。以上代码都是示例,像其它复杂的功能,需要自己添加。比如如何插入检查点,如何在excel中体现循环和判断。等等等等。大家慢慢来吧。