第二篇:花时间打个小框架

上回说到,一时无聊用类把自定义的对象来了个大封装。起初只是为了方便写代码,感觉有个小规范好一点点。但是旁边的峰锅锅说,既然你都写成了类,为什么不顺便做一个由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中体现循环和判断。等等等等。大家慢慢来吧。

猜你喜欢

转载自blog.csdn.net/yzh900927/article/details/20564525