1、为什么要使用框架?
框架是一组自动化测试的规范、测试脚本的基础代码,以及测试思想、惯例的集合。可用于减少冗余代码、提高代码生产率、提高代码重用性和可维护性。例如QTestWare 就是QTP 自动化测试框架中的一类。
2 、SAFFRON 简介
SAFFRON 是针对Web 开发的一个简单的QTP 测试框架原型,是Adam Gensler 于06 年写的,需要QTP 9.1 版本以上。完整的SAFFRON 脚本代码可到以下地址获取:http://www.itestware.com/ctest/index.php?option=com_content&view=article&id=62:webqtp-saffron&catid=35:testing_is_believing
3 、如何使用SAFFRON?
SAFFRON 框架以外部VBS 文件的形式出现,因此使用方法比较简单,直接在测试脚本中以资源形式导入即可使用,如图所示:
导入后,可在"Available Keywords" 视图中看到SAFFRON 的所有函数,如图所示:
选中某个函数,拖拽到专家视图的编辑器中,如图所示:
后接一个URL 地址,例如http://www.itestware.com ,即可使用SAFFRON 框架中的BrowseTo 函数导航到指定的URL 地址,如下脚本所示:
'BrowseTo(url)
BrowseTo “http://www.itestware.com
4 、SAFFRON 框架代码剖析
为了深入了解SAFFRON ,以及框架的使用方法,下面我们将分别介绍SAFFRON 中的主要函数,对SAFFRON 代码进行深入剖析。
4.1 导航到指定URL
SAFFRON 使用名为BrowseTo 函数来负责导航到指定的URL ,如果浏览器尚未启动,则先调用函数Launch 来打开浏览器。BrowseTo 函数的定义如下所示:
Public Function BrowseTo (url)
thirdlevel = ""
Report micPass, "Navigate to URL", "Navigating to URL: " & Quote(url)
If initialized Then
Execute GenerateDescription("Browser") & "Navigate " & Quote(url)
Else
Launch "website", url
End If
Reporter.Filter = rfDisableAll
End Function
在脚本中,会判断是否初始化了浏览器,如果有则执行导航动作,导航到指定的URL 。导航动作是执行这行脚本来完成的:
Execute GenerateDescription("Browser") & "Navigate " & Quote(url)
Execute 是一个用于执行指定VBScript 脚本语句的函数,GenerateDescription 函数的定义如下所示:
' Generates a generic description based up on the "level" viarable
' levelstr - will be one of the values that is in the level array
' returns - string representative of the object hierarchy
Public Function GenerateDescription (levelstr)
l = IndexOf(level, levelstr)
If l >=0 Then
fdesc = level(0) & "(" & Quote(desc(0)) & ")."
If l >= 1 Then
fdesc = fdesc + level(1) & "(" & Quote(desc(1)) & ")."
If 2 >= l Then
If thirdlevel <> "" Then
fdesc = fdesc + level(2) & "(" & Quote(desc(2)) & "," & Quote("name:=" & thirdlevel) & ")."
End If
End If
End If
End If
GenerateDescription = fdesc
End Function
4.2 返回测试对象的描述
GenerateDescription 函数用于返回对象的描述性语句,例如,指定Browser ,则返回如下语句:
"Browser("miclearcase/" target="_blank" >cclass:=Browser")."
该语句代表了当前浏览器对象,并且后面加了个点号,这是为了方便后接"Navigate " 这个浏览器对象的导航操作,以及指定的URL 字符串,例如"http://blog.csdn.net/testing_is_believing " 。在Execute 时,其实执行的VBScript 语句如下所示:
Browser("micclass:=Browser").Navigate "http://blog.csdn.net/testing_is_believing "
经过SAFFRON 的框架封装后,则只需要使用如下语句即可达到同样的效果:
BrowseTo "http://blog.csdn.net/testing_is_believing "
4.3 启动浏览器
SAFFRON 使用名为BrowseTo 函数来负责导航到指定的URL ,但是如果浏览器未启动,则会先调用函数Launch 来打开浏览器。Launch 函数的定义如下所示:
prepares the framework for usage, and configures all internal framework
' variables and structures
' apptype - used to launch different types of applications based
' upon different technologies -- currently there is only web
' val - string that represents what to launch
' returns - always returns true
Public Function Launch (apptype, val)
If "website" = apptype Then
thirdlevel = ""
Report micPass, "Initialize", "Initializing Framework"
level = split(webLevels, leveldelimiter, -1, 1)
desc = split(webLevelsDesc, leveldescdelimiter, -1, 1)
object = split(objects, objectdelimiter, -1, 1)
objectDescription = split(objectsDescription, objectsDescriptiondelimiter, -1, 1)
CloseBrowsers
Set IE = CreateObject("InternetExplorer.Application")
IE.visible = true
IE.Navigate val
While IE.Busy
wait 1
Wend
End If
initialized = true
Launch = true
End Function
可看到脚本中创建了IE 的COM 对象,然后设置IE 的Visible 属性设置为Tue ,让浏览器可见,然后调用IE 对象的Navigate 方法导航到指定的URL 。除了创建IE 的COM 对象外,在Launch 函数中还进行框架其它方面的初始化。
4.4 给指定字符串前后加双引号
在BrowseTo 函数的定义脚本中,调用了一个名为Quote 的函数,该函数的定义如下所示:
' generates a string with embedded/surrounding quotes
Public Function Quote (txt)
Quote = chr(34) & txt & chr(34)
End Function
该函数的作用是给指定的字符串前后加上双引号字符,例如下面代码
Msgbox "The message is " & Quote("hello world!")
执行结果显示如图所示。
如果我们不使用这个函数,则需要这样写我们的代码来实现同样的功能:
Msgbox "The message is ""hello world!"""
很明显,这样的写法写出来的代码的可读性和可维护性都差一截。
4.5 点击链接
作为一个针对WEB 应用的脚本框架,除了能启动浏览器导航到指定的页面外,还需要针对页面的各种元素进行测试操作,例如链接的点击、按钮的点击操作。在SAFFRON 框架中,使用Activate 函数来点击链接、按钮,其函数定义如下所示:
' Activates an object based upon its object type
' objtype - the type of object should be limited to values in the object array
' text - identifying text for the control - for a link, it's the text of the link
Public Function Activate (objtype, text)
localDesc = ""
If thirdlevel <> "" Then
localDesc = GenerateDescription(level(2))
Else
localDesc = GenerateDescription(level(1))
End If
AutoSync()
Select Case objtype
Case "Link"
Execute localDesc & GenerateObjectDescription("Link","innertext:=" & text) & "Click"
Report micPass, "Link Activation", "The Link " & Quote(text) & " was clicked."
Case "WebButton"
Execute localDesc & GenerateObjectDescription("WebButton", "value:=" & text) & "Click"
Report micPass, "WebButton Activation", "The WebButton " & Quote(text) & " was clicked."
End Select
End Function
函数首先判断对象的类型,然后根据对象类型分别处理,如果是链接对象,则通过以下语句组合成可执行的VBScript 语句,然后用Execute 函数来执行:
Execute localDesc & GenerateObjectDescription("Link","innertext:=" & text) & "Click"
如果是按钮对象,则组合成:
Execute localDesc & GenerateObjectDescription("WebButton", "value:=" & text) & "Click"
在这里,调用了GenerateObjectDescription 函数,GenerateObjectDescription 函数的作用与GenerateDescription 函数的作用类似,都是用于返回一个测试对象的描述,不同的是GenerateObjectDescription 函数需要传入测试对象的描述数组,GenerateObjectDescription 函数的定义如下:
' Generates an object description based upon the object, and objectDescription arrays
' obj - name of the object in the object array
' prop - additional property to help uniquely identify the object
' returns - a string representative of the object description
Public Function GenerateObjectDescription (obj, prop)
i = IndexOf(object, obj)
ndesc = ""
If i <> -1 Then
ndesc = obj & "(" & Quote(objectDescription(i)) & "," & Quote(prop) & ")."
End If
GenerateobjectDescription = ndesc
End Function
有了Activate 函数,我们在写脚本的时候就可以充分利用,简化脚本的编写,例如下面是两句简单的脚本,分别点击页面上的一个链接和一个按钮:
Activate "Link", "Person"
Activate "WebButton", "Search"
在Activate 函数中,调用了一个名为AutoSync 的函数,该函数的作用与QTP 的Sync 方法是一样的,只是在外面封装了一层,函数定义如下所示:
' waits for the web page to finish loading
Public Function AutoSync
Execute GenerateDescription("Browser") & "Sync"
End Function
AutoSync 函数用于等待WEB 页面加载完成。
4.6 一个小例子
到现在为止,我们可以使用SAFFRON 的Launch 、BrowserTo 和Activate 函数来编写简单的脚本启动浏览器,导航到指定的页面,点击链接和按钮,例如下面就是一个综合了这几个功能的脚本:
' 启动浏览器
Launch "website","http://127.0.0.1:1080 "
' 导航到“http://127.0.0.1:1080/WebTours ”
BrowseTo "http://127.0.0.1:1080/WebTours/ "
' 点击名为“administration ”的链接
Activate "Link","administration"
该脚本调用SAFFRON 框架的Launch 函数启动IE 浏览器,然后导航到“http://127.0.0.1:1080/WebTours ”,点击如图所示的页面中名为“administration ”的链接。
脚本的测试结果如图所示。
4.7 检查对象是否存在
前面的小例子仅仅实现了启动浏览器、导航、点击链接和按钮的功能,如果要组成一个完整的测试用例,还缺少一些东西,例如检查指定的对象是否存在,在SAFFRON 中,用Verify 函数来实现这个功能,Verify 函数的定义如下所示:
' Verify the Existence of an object
' objtype - values should be limited to values in the object array
' text - multi-purpose argument that indicates what to verify
' - for a link, or button, it's the text of the control
' - for a list, it's the name of the control
' - for a frame, it's the name of the frame
Public Function Verify (objtype, text)
rval = false
localDesc = ""
estr = ""
If thirdlevel <> "" Then
localDesc = GenerateDescription(level(2))
Else
localDesc = GenerateDescription(level(1))
End If
AutoSync()
Select Case objtype
Case "Page"
Execute "rval = " & GenerateDescription(level(1)) & "Exist (0)"
If rval Then
Execute "title = " & GenerateDescription(level(1)) & "GetROProperty(" & Quote("title") & ")"
If title = text Then
rval = true
Else
rval = false
End If
End If
Case "CurrentFrame"
If thirdlevel <> "" Then
estr = "rval = " & localDesc
End If
Case "Link"
estr = "rval = " & localDesc & GenerateObjectDescription("Link", "innertext:=" & text)
Case "WebButton"
estr = "rval = " & localDesc & GenerateObjectDescription("WebButton", "value:=" & text)
Case "WebList"
estr = "rval = " & localDesc & GenerateObjectDescription("WebList", "name:=" & text)
Case "WebEdit"
estr = "rval = " & localDesc & GenerateObjectDescription("WebEdit", "name:=" & text)
End Select
If estr <> "" Then
Execute estr + "Exist (0)"
End If
If rval Then
Report micPass, objtype & " Verification", "The " & objtype & " " & Quote(text) & " was verified to exist"
Else
Report micFail, objtype & " Verification", "The " & objtype & " " & Quote(text) & " was not found"
End If
If "True" = rval Then
rval = True
Else
rval = False
End If
Verify = rval
End Function