QTP通用性的自动化测试框架:
Frank
如果在一般自动化测试框架上(连接QC)再考虑下面四个特性,那么就极大地提高了扩展性和重用性,而且可以降低QTP编程错误。就成为了合适的大型,多平台项目的自动化测试框架。
1. 将一些基础的函数封装在DLL文件中,我们以.net为例。
在DLL中我们利用了C#语言的特性,编写很多实用的通用性function。如果需要还可以组织成类。
在QTP调用DLL的方法或含DLL方法的类:
DotNetDllPath = “C:\DotNet.dll” set dotInstance = DotNetFactory.CreateInstance("DotNet.Name", DotNetDllPath) dotInstance.Method |
可以把相似的function封装在类中,然后在library 生成这个类的对象实例(newclassName),那么在QTP中可以直接用这个对象 (实例)及其所有的方法。从而极大地拓展了QTP的功能。
2. 注册新的方法和重写QTP方法。因为注册新的方法比较简单,步骤及原理和重写QTP方法一样,所以下面以重写QTP方法为例子。
这里面涉及的最重要的一条语法是:
RegisterUserFunc TOClass, MethodName, FunctionName, SetAsDefault E.g. RegisterUserFunc "WebEdit", "Set", "MySet" “Set” 是QTP可以显示的新的或自带的方法。 “MySet” 是自己写function 的name。Function FunctionName |
大家都应用(SetTOproperty, GetROPropery等)时属性值的名称是绝对不能出错的,为了防止出错,我们可以重写方法。
以Dialog().SetTOProperty("windowid", win01)为例,我们对每一次Dialog的SetTOProperty的windowid属性编码, 就得写这就话,而且"windowid"拼写不能错;而且Static,WinButton对象都有这样的麻烦。
现在我们写一个这样的方法:
Function UpdateWindowId(obj, newValue) obj.SetTOProperty "window id", newValue Set UpdateWindowId = obj End function RegisterUserFunc "Dialog", "UpdateWindowId", " UpdateWindowId" RegisterUserFunc "Static", "UpdateWindowId", "UpdateWindowId" RegisterUserFunc "WinButton", "UpdateWindowId", "UpdateWindowId" |
这样就彻底解决了这些对象,在每次编程SetTOProperty 的"windowid"属性时,要找属性的name是什么。
其实这样做是不够的,你可以很轻松SetTOProperty 的"windowid"属性时,但是其他的很多属性呢?比如说”text”。所以我们写一个更通用的方法来解决SetTOProperty的属性值问题。
通用性的SetTOProperty方法是:
Function Update(obj, propertyName, val) obj.SetTOProperty propertyName, val Set Update = obj End function |
所以上面的UpdateWindowId不用具体实现,只要调用通用性的Update方法:
Function UpdateWindowId(obj, newValue) Set UpdateWindowId = Update(obj, "window id", newValue ) End function |
像set (比如SetTOProperty) 方法是直接这样实现的。但是像get(比如getTOProperty)方法就除了调用GetROProperty外,还要考虑这个方法是否已经被注册了,如果已经注册了,调用新的注册方法,否则调用GetTOProperty方法。
所以通用性的getTOProperty方法是:
function GetRuntimePropertyOrOverride(obj, strProperty, strApiPropertyName) dim qtpName : qtpName = GetFullQtpName(obj) dim func : set func = GetRef(qtpName & "." & strApiPropertyName) if not IsEmpty(func) then GetRuntimePropertyOrOverride = func(objSender) exit function end if GetRuntimePropertyOrOverride = GetRoProperty(obj, strProperty) end function
function GetFullQtpName(obj) dim fullQtpName: fullQtpName = obj.GetTOProperty("class Name") & "(""" & _ obj.GetTOProperty("TestObjName") & """)" dim objCurrent : set objCurrent = obj
do while not IsEmpty(objCurrent.GetTOProperty("parent")) set objCurrent = objCurrent.GetTOProperty("parent") fullQtpName = objCurrent.GetTOProperty("class Name") & "(""" & _ objCurrent.GetTOProperty("TestObjName") & """)" & "." & fullQtpName loop
GetFullQtpName = fullQtpName end function |
3. 关于多浏览器的问题比如IE不同版本和Firefox。
最好定义一个类,把所有浏览器的型号作为属性。
class BrowserType public property get IE7 IE7 = "IE7" end property
public property get IE8 IE8 = "IE8" end property
public property get FF3 FF3 = "FF3" end property End class |
再定义一个类,就是QTP要直接运用的这个类的对象。因为我们设计的是面对多浏览器窗口的,所以我们首先生成一个储存browser的Dictionary(比如key(BrowserName)-Vlaue(Browser))。这个类里面有属性:browser_pro(broswer的reference)和Type(浏览器的type)和对外用get和set方法。要实现我们平常浏览器切换等功能,下面的方法就很好的实现了:
get CurrentBrowserName {返回browser_pro } SetCurrentBrowser(strBrowserName) {检查browserName 是否在Dictionary中,browser_pro .SetTOProperty "hwnd", m_browsers(strBrowserName).Hwnd} GetBrowser(strBrowserName) {检查browserName 是否在Dictionary中,然后返回它的Value(browser对象)} AddExistingBrowser(browserName, browserDescription) {首先看browserName 是否存在于Dictionary,不存在的话加到Dictionary中} AddNewBrowser(browserName) {看browser type和上面类BrowserType的那个属性相等,调用不同的浏览器程序(SystemUtil.Run iexplore.exe/firefox.exe),最后把新生成的browser加到Dictionary } RemoveAndCloseBrowser(browserName): {检查browserName 是否在Dictionary中,然后对它的Value(browser对象)调close方法} RemoveAndCloseAllBrowsers(): {遍历Dictionary所有元素,分别调用RemoveAndCloseBrowser} |
4. 自定义result report.这个问题比较好解决。QTP每次运行结果会生成xml的result report。但是显然不够大中型项目的需要,好在这个问题在技术上好解决。这个没有统一的写法,项目不同report的方式内容也不同,具体代码的话,Google一下.
可以参考文章:http://blog.youkuaiyun.com/franktan2010/article/details/7236944