您的位置:首页 > 编程语言 > Qt开发

QTP自动化测试框架:第六章 主要方法介绍(框架功能)

2014-04-21 11:07 423 查看
时间有点晚了,我这里就直接拿出几个最关键的一方

第一,将对象库转换成XML文件,并从中提取出对象字符串,我们输入 的可能仅仅是按钮名称,但需要从中取得对象的整个父对象。

TestDllFilePath=FrameworkPath+"Test_DotNetDll\QTPBuildObjectLayer.dll"
Set FileOperation= DotNetFactory.CreateInstance("System.IO.File")
Set DirectoryOperation= DotNetFactory.CreateInstance("System.IO.Directory")
Set ObjectBuild= DotNetFactory.CreateInstance("QTPBuildObjectLayer.BuildObject",TestDllFilePath)
Set XMLFileExport=CreateObject("Mercury.ObjectRepositoryUtil")
Set TestDataDictionary=CreateObject("Scripting.Dictionary")

这里是前提,需要用不对劲这些外部dll。或者通过dotnetfactory创建,直接高用基于.net的方法


第二,处理对象库及转换成XML.

<pre name="code" class="plain">'FunctionName:BuildObject
'Description:convert object name to string, eg. convert "Login" to window("Main").Winbutton("Login"), description program is supported
'FunctionType:Function Utility , referenced by ActionEntry

Function BuildObject(ObjectName)
If left(ObjectName,3)="Dsc" Then
BuildObject=Dsc_Object(ObjectName)     'reserved
Else
RepositoriesNumTemp=1
For RepositoriesNumTemp=1  to RepositoriesCollection.Count
RepositoryExportToXMLFile RepositoriesNumTemp
ObjectFound = ConvertToObjectLayer(ObjectName)
If  ObjectFound <> "" Then
BuildObject = ObjectFound
Exit for
End If

Next
End If
End Function

'FunctionName:LoadRepositories
'Description:if Repositories_Name give a repository,then add it to current actions,else
'FunctionType: Function Utility,referenced by ActionEntry funcion

Sub LoadRepositories(RepositoriesName)
TestRepositoriesFilePath=TestRepositoriesPath+RepositoriesName
If RepositoriesCollection.Find(TestRepositoriesFilePath)=False Then
RepositoriesCollection.Add(TestRepositoriesFilePath)
else
RepositoriesCollection.Remove(TestRepositoriesFilePath)
RepositoriesCollection.Add(TestRepositoriesFilePath)

end if
End Sub

'FunctionName:RepositoryExportToXMLFile
'Description :Export all repositorys to xml files.
'Function Type:Utility Function,referenced by build Object

Sub RepositoryExportToXMLFile(RepositoryIndex)

If FileOperation.Exists(TempXMLFilePath) Then
FileOPeration.Delete(TempXMLFilePath)
End If
XMLFileExport.ExportToXML (FrameworkFolderPath+RepositoriesCollection.Item(RepositoryIndex)),TempXMLFilePath

End Sub

'FuncitonName:ConvertToObjectLayer
'Description:Find object name in temp.xml file and recombine to a string like windows("test").winbutton("hello")
'Function:Function Utilities ,referenced by BuildObject

Function ConvertToObjectLayer(ObjectName)

ObjectArray=ObjectBuild.FilePathObjectName(TempXMLFilePath,ObjectName)
If ObjectArray<>"" Then
ObjectArray=Split(ObjectArray,"@")
ConvertToObjectLayer=ObjectArray(Ubound(ObjectArray))
ELSE
ConvertToObjectLayer=""

End If

End Function




上面可以 看到高有季buildobjeectt方法 ,这个其实是net写的dll.具体 代码如下,这里千万不能如错,为了考虑以后兼容,我在这里返回的是数组。原则QTP对象库中是不要出现两个同名的对象。这个地方是千万不能出错的。为了简单和效率就用了linq to xml.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Xml.Linq;

namespace QTPBuildObjectLayer
{
public class BuildObject
{

XNamespace NameSpace = "http://www.mercury.com/qtp/ObjectRepository";

public string FilePathObjectName(string FilePath, string LogicName, string ObjectType = "")
{

string ParentNode = "";
string ChildNode = "";
string BuildObjectString = "";
String ObjectList = "";

try
{

if (FilePath == null || LogicName == null)
{

ObjectList = "Please input right FilePath or LogicName";
return ObjectList.ToString();
}
XDocument test = XDocument.Load(FilePath);
var Query = from c in test.Descendants(NameSpace + "Object")
where ((ObjectType == "") ? (c.Attribute("Name").Value == LogicName) : (c.Attribute("Name").Value == LogicName && c.Attribute("Class").Value == ObjectType))
select new
{
IsChildObject = c.Parent.Name.Equals(NameSpace + "ChildObjects"),
LogicNameClass = c.Attribute("Class").Value
//ChildObjectsElementName = c.Attribute("Name").Parent.Parent.Name,
//ParentAttributionName = c.Attribute("Name").Parent.Parent.Parent.Attribute("Name").Value,
//ParentAttributionValue = c.Attribute("Name").Parent.Parent.Parent.Attribute("Class").Value

};

foreach (var Item in Query)
{
ChildNode = "";

ChildNode = Item.LogicNameClass + "(\"" + LogicName + "\")";
if (Item.IsChildObject)
{
ParentNode = ParentNode + BuildParentNode(FilePath, LogicName, Item.LogicNameClass);

}

BuildObjectString = ParentNode + ChildNode;
ObjectList = ObjectList + "@" + (BuildObjectString);

}

return ObjectList;

}

catch (Exception exception)
{
ObjectList = exception.ToString();
return ObjectList;
}
}

public string BuildParentNode(String FilePath, string LogicName, String LogicNameClass)
{
string ParentNode = "";
XDocument ParentObject = XDocument.Load(FilePath);
try
{
var Query1 = from b in ParentObject.Descendants(NameSpace + "Object")
where (b.Attribute("Name").Value == LogicName) && (b.Attribute("Class").Value == LogicNameClass)
select new
{

ParentIsChildObject = b.Parent.Parent.Name.Equals(NameSpace + "ChildObjects"),
ParentAttributionName = b.Parent.Parent.Attribute("Name").Value,
ParentAttributionClass = b.Parent.Parent.Attribute("Class").Value
};

foreach (var Item1 in Query1)
{
ParentNode = Item1.ParentAttributionClass.ToString() + "(\"" + Item1.ParentAttributionName + "\").";
if (Item1.ParentIsChildObject)
{
LogicName = Item1.ParentAttributionName;
LogicNameClass = Item1.ParentAttributionClass;
ParentNode = ParentNode + BuildParentNode(FilePath, LogicName, LogicNameClass);

}
// break;
}

return ParentNode;
}
catch (Exception)
{
return "BuildChildObject Failed";
}
}
}
}


下面也是比较关键的,写了一大堆 东西就是为了实现 一个功能,把转换后的对象字符串、测试数据与对应的事件关联起来,即将读取到的window("aa").edit("b") 及111111 set拼接在一起执行,然后找到对应的方法并执行,这里每一个set.click.doubleclick都是作为 action部分的,每个事件一个方法,如果执行失败就截图并记录即可。

'FunctionName: ExecuteActionSteps
'Description: Execute all actions from this function
'FunctionType:Framework core partion, referenced by Utility Function library,ActionEntry function

Function ExecuteActionStpes(strKeyWords,strObjectName,strParameter,strRepositoriesName)
If strKeyWords="" Then
Reporter.ReportEvent micFail,"Function ActionEntry","Business_Function is null"
Exit function
End If
Environment("DefinedActionName")=strKeyWords
If strRepositoriesName <> "" Then
LoadRepositories RepositoriesName
End If

If strObjectName <>"" Then
If ucase(left(strObjectName,4))="DSC_" Then
strObject=DespritionObject(strObjectName)
else
strObject=BuildObject(strObjectName)

End if

If strObject="" OR strObject="Not Found" Then
Reporter.ReportEvent micFail,"ObjectString:"+strObjectName,"Build object failed,please check your entry or object is described correctly"
Exit function
End If

If strParameter = ""  Then
Eval(Trim(strKeyWords)+"("+strObject+")")
else
TestParameter=ReOrganizeParameter(strParameter)
Eval(Trim(strKeyWords)+"("+strObject+","+TestParameter+")")
End If

Else

If strObjectName="" and strParameter="" Then
Eval(Trim(strKeyWords))
else If strObjectName="" Then
TestParameter=ReOrganizeParameter(strParameter)
Eval(Trim(strKeyWords)+"("+TestParameter+")")
End If
End If

End If

End Function


根据eval的结果,自动跳转到action方法部分。以下仅为一个,示例,所以有的均可参照这种方法。其它的类似就不一一重复

'FunctionName:Enter_Value_In_Field
'Descriptions:Enter vlaue in edit box or text box etc.
'Input Parameter:Object String,input parameter and if value is encryped flag
'FunctionType: Framework core functions, referenced by execute action steps

Function Enter_Value_In_Field(strObject,strParameter,IsEncryped)
Enter_Value_In_Field="FAIL"

If strObject.exist(10) Then
strObject.set ""
If Ucase(IsEncryped)="YES" Then
EncypParameter=Crypt.Encrypt(strParameter)
strObject.SetSecure EncypParameter
else
strObject.set strParameter
End If

Enter_Value_In_Field="PASS"

call LogAndCaptureImage(strObject,"Enter_Value_In_Field","PASS","Object:"+strObject.Tostring+" executed successfully")
else
Enter_Value_In_Field="FAIL"
call  LogAndCaptureImage(strObject,"Enter_Value_In_Field","FAIL","Object:"+strObject.Tostring+" Not Found")
End If
End Function


最后就是执行的结果需要进行截图,并记录运行每一步的结果

'FunctionName:LogAndCaptureImage
'Descriptions:If Function parameter contain object name, log action execute status and capture img ,if object is null,log execute status
'Input Parameter:strObjectName,ReportName,ReportStatus,ReportDetails
'Output Parameter:None
'FunctionType:Global function, referenced by all actions

Function LogAndCaptureImage(ObjectName,ActionStep,ReportStatus,ReportDetails)
ImageFilePath=Environment("FrameworkPath")+"Test_Result\"+Environment("DefinedTestName")+"\"+cstr(Environment("DefinedTestIteration"))+"_Image"
FormattedCurrentDateTime=year(Date)&month(date)&day(date)&hour(now)&minute(now)&second(now)
ReportStep=ActionStep
ImageFileFullPath=""
If Not IsEmpty(ObjectName) and IsObject(ObjectName)  Then
ReserveObject=split(trim(Replace(ObjectName.Tostring,"["," "))," ")
ReserveObjectName=ReserveObject(Lbound(split(ObjectName.Tostring," ")))
ObjectString=BuildObject(ReserveObjectName)
If Ubound(split(ObjectString,")."))>0 Then
TempArray=split(ObjectString,").")
TempObject="set  ObjectToCapture="+TempArray(0)+")"
ELSE
TempObject="set  ObjectToCapture="+ObjectString
End If
Execute TempObject
If DirectoryOperation.exists(ImageFilePath) = "False" Then
DirectoryOperation.CreateDirectory(ImageFilePath)
End If
ImageFileFullPath=ImageFilePath+"\"+FormattedCurrentDateTime+".png"
If ObjectToCapture.exist(5) and Environment("ImageCaptureLevel") <> "FailedOnly" Then
ObjectToCapture.CaptureBitmap ImageFileFullPath,true
ObjectToCapture.CaptureBitmap ImageFileFullPath,true

If ReportStatus="PASS" Then
If Environment("ImageCaptureLevel") <> "FailedOnly" Then
Reporter.ReportEvent micPass,ReportStep,ObjectName.Tostring+"Finished", ImageFileFullPath
else
'Reporter.ReportEvent micPass,ReportStep,ReportDetails+":  "+"<img src='"+ImageFilePath+"\"+FormattedCurrentDateTime+".png"+"' />"
Reporter.ReportEvent micPass,ReportStep,ReportDetails
End if
call GenerateReport(ReportStep,"PASSED",ReportDeatils,ImageFileFullPath)
else
Reporter.ReportEvent micFail,ReportStep,ReportDetails,ImageFileFullPath
call GenerateReport(ReportStep,"FAILED",ReportDeatils,ImageFileFullPath)
End If

Else
If ReportStatus="PASS" Then
Reporter.ReportEvent micPass,ReportStep,ReportDetails
call GenerateReport(ReportStep,"PASSED",ReportDeatils,"")
else
Reporter.ReportEvent micFail,ReportStep,ReportDetails
call GenerateReport(ReportStep,"FAILED",ReportDeatils,"")
End If
End if
End If

End Function


最后一步是压缩成ZIP文件将结果发送至指定邮箱。这个功能多上有很多,这里就不详细介绍了。

'FunctionName:ZipFile
'Description:Zip a file to *.ZIP
'InputParameter:Source file path,desination file path
'FunctionType:Framework core function

Function ZipFile(SourceFolder,ZipFilePath)
Set Fso=createobject("Scripting.FileSystemObject")
for each files in Fso.GetFolder(SourceFolder).Files
If lcase(right(files,4))=".zip" Then
Fso.DeleteFile files.path,True
End If
Next

set File=Fso.CreateTextFile(ZipFilePath,true)
File.Write "PK"& Chr(5) & Chr(6) & String(18, Chr(0))
File.Close

Set objShell=CreateObject("Shell.Application")
Set objSource=objShell.NameSpace(SourceFolder)
Set objFolderItem=objSource.Items()

Set objTarget=objShell.NameSpace(ZipFilePath)
intOptions=256

objTarget.CopyHere objFolderItem,IntOptions

Do
wait 0.5
Loop Until objTarget.Items.Count >0

Set File=Nothing
Set objShell=Nothing
Set WScript=Nothing
End Function

'FunctionName:SendMail
'Description:SendMail to specify user and specify server
'InputParameter:useraccount,userpassword,serveraddress,sendto,mailsubject,mailbody,attachment
'FunctionType:Framework Core function

Function SendMail(UserAccount,UserPassword,SendTo,MailSubject,MailBody,Attachment)
NameSpace="http://schemas.microsoft.com/cdo/configuration/"
Set Email=CreateObject("CDO.Message")
Email.From=UserAccount
Email.To=SendTo
Email.Subject=MailSubject
Email.TextBody=MailBody
If Attachment<>"" Then
If FileExists(Attachment) Then
Email.AddAttachment Attachment
End If
End If

AccountInfo=split(UserAccount,"@",2,1)

With Email.Configuration.Fields
.item(NameSpace&"sendusing")=2
.item(NameSpace&"smtpserver")="smtp."+AccountInfo(1)
.item(NameSpace&"smtpserverport")=25
.item(NameSpace&"smtpauthenticate")=1
.item(NameSpace&"sendusername")=AccountInfo(0)
.item(NameSpace&"sendpassword")=userpassword
.Update
End With

Email.Send
Set Email=nothing
End Function

再补充几个功能,进入节点,和退出QTP自带report结点

'FunctionName:EnterNode
'Description:insert a node,then all event will be logged under this node
'InputParameter:NodeName---TestInteration or ActionInteration;NodeContent,Node description
'OutPutParameter:Node
'FunctionType:Reporting module,Referenced by LogAndCaptureImage

'@Description Create a Node ,then all reporter event will under this node,this function must work together with ExitNode
Public Function EnterNode(ByRef NodeName, ByRef NodeContent)

Set DiscriptionNodeData=CreateObject("Scripting.Dictionary")
DiscriptionNodeData("Status")=MicDone
DiscriptionNodeData("PlainTextNodeName")=NodeName
DiscriptionNodeData("StepHtmlInfo")=NodeContent
DiscriptionNodeData("DllIconIndex")=210
DiscriptionNodeData("DllIconSelIndex")=210
DiscriptionNodeData("DllPath")=Environment("ProductDir")+"/bin/ContextManager.dll"
intContext=Reporter.LogEvent("User",DiscriptionNodeData,Reporter.GetContext)
Reporter.SetContext intContext
End Function

'FunctionName:ExitNode
'Description:Exit current node
'InputParameter:None
'OutputParameter:Node
'FunctionType:Reporting Module,referenced by LogAndCaptureImage

'@Description Exit current node
Public Function ExitNode()
Reporter.UnSetContext
Set DiscriptionNodeData=Nothing
End Function
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: