如何使用SoapUI/Groovy将测试结果添加到质量中心测试运行

如何使用SoapUI/Groovy将测试结果添加到质量中心测试运行,groovy,soapui,hp-quality-center,Groovy,Soapui,Hp Quality Center,我有一个场景,需要将SoapUI测试用例中的测试结果添加到HP Quality Center中的相关测试用例中。我怎样才能用Groovy做到这一点。质量中心提供了一个OTA API来与之接口;但是,它是为了使用Microsoft COM结构编写的,Java/Groovy没有本机使用的方式。幸运的是,有一个Groovy库,它允许Groovy使用COM接口 在完成每个设置后,我会给出以下示例代码: import org.codehaus.groovy.scriptom.* def tstCaseN

我有一个场景,需要将SoapUI测试用例中的测试结果添加到HP Quality Center中的相关测试用例中。我怎样才能用Groovy做到这一点。

质量中心提供了一个OTA API来与之接口;但是,它是为了使用Microsoft COM结构编写的,Java/Groovy没有本机使用的方式。幸运的是,有一个Groovy库,它允许Groovy使用COM接口

在完成每个设置后,我会给出以下示例代码:

import org.codehaus.groovy.scriptom.*

def tstCaseName = "NAME_OF_TESTCASE"
tstCaseName = tstCaseName.replaceAll(/[ ]/) {  match ->
    "*"
}

Scriptom.inApartment
{
    //  Create an entry point for QC
    def tdc = new ActiveXObject ('TDApiOle80.TDConnection')

    //  Connect to QC, Login with Credentials, connect to Project
    tdc.InitConnectionEx('http://qc.example.com/qcbin')
    tdc.Login('USER_NAME', 'PASSWORD')
    tdc.Connect('DOMAIN_NAME','PROJECT_NAME')

    //  Find the set of tests in the Test Plan
    tsFolder = tdc.TestSetTreeManager.NodeByPath('Root\\PATH\\TO\\TEST\\CALENDAR\\Spaces are allowed')
    tsList = tsFolder.FindTestSets('NAME_OF_TEST_CALENDAR')
    tsObject = tsList.Item(1)

    //  Get the list of TestCases in the Test Plan and filter it down to the one Test Case we are interested in
    TSTestFact = tsObject.TSTestFactory 
    tstSetFilter = TSTestFact.Filter
    tstSetFilter.Filter["TS_NAME"] = '*' + tstCaseName
    TestSetTestsList = TSTestFact.NewList(tstSetFilter.Text)
    tsInstance = TestSetTestsList.Item(1) 

    //  Create a new Test Run
    newRun= tsInstance.RunFactory.AddItem('Run_Auto')
    newRun.Status = 'Not Completed' 
    newRun.Post() 
    newRun.CopyDesignSteps()
    newRun.Post() 

    //  Populate Auto Run Test step Data
    def tsStepData = new Object[3]
    tsStepData[0]='Auto Data'
    tsStepData[1]='Not Completed'
    tsStepData[2]='Results from Automated Test'
    //  Create new Test Step in the run with our Auto Run Data
    tsSteps = newRun.StepFactory.AddItem(tsStepData)
    tsSteps.Field['ST_ACTUAL'] = 'These are the actual results from my test!!'
    tsSteps.post()
} 

我在scriptom方面遇到了问题,而且还是Groovy的新手,但有质量中心的经验,我为SoapUI测试编写了一个分解脚本,将结果写入平面文件,然后使用VBScript将数据拉入

这些脚本使用硬编码值,但希望能让您开始:

VAPI-XP脚本-

'*******************************************************************
'调试,CurrentTestSet,CurrentTest,CurrentRun
'调试,CurrentTestSet,CurrentTSTest,CurrentRun
'**************************************************************************
子测试_Main(调试、CurrentTestSet、CurrentTest、CurrentRun)
'***VBScript限制***
“'On Error Resume Next'语句抑制运行时脚本错误。
'要以正确的方式处理运行时错误,您需要输入“If Err.Number 0 Then”
'在可能导致此类运行时错误的每行代码之后。
出错时继续下一步
'清除输出窗口
t输出,完毕
'**************************************************************************
'定义SOAPUI可执行bat文件和项目xml的路径
'项目xml包含需要执行的测试用例
'**************************************************************************
Dim trPath'指向测试运行程序bat文件的路径
SoapUI Groovy脚本生成的Dim soapResults结果文件
Dim projFP的SoapUI项目文件路径
Dim spath结果文件-当前未使用
Dim tf“测试工厂对象”
Dim ts的测试ID
Dim TSuite’SoapUI测试套件名称
Dim Tcase的SoapUI测试用例名称
Dim resultsP的SoapUI输出报告位置-当前未使用
projFP=“C:\SOME\FILE\PATH\soapui project.xml”
spath=“C:\File.txt”
trPath=“C:\program files\SmartBear\SoapUI-Pro-4.5.2\bin\testrunner.bat”
soapResults=“C:\Groovy\u Report\test1.txt”
'用于SoapUI执行的字符串
TSuite=“SOAPUI\u TESTSUITE\u NAME”
Tcase=“SOAPUI\u TESTCASE\u NAME”
resultsP=“C:\SoapResults\”&Tcase
设置tf=TDConnection.TestFactory
设置ts=tf.项目(字段(“ts测试ID”))
'**************************************************************************
'调用SOAPUI并执行所选项目
'**************************************************************************
调用APUIClient trPath、projFP、TSuite、Tcase、resultsP、CurrentTest、CurrentRun
'**************************************************************************
'从文本文件中获取结果以运行测试用例的步骤
'**************************************************************************
'等待1秒以允许较大的文件完成写入
t输出。打印“开始等待10”
XTools.睡眠1000
t输出。打印“结束等待10”
'获取结果文件并写入以运行步骤
getResultsToQC CurrentRun,soapResults
'**************************************************************************
'处理运行时错误
'**************************************************************************
如果没有调试,那么
如果错误号为0,则
t输出.Print“运行时错误-执行SOAPUI:输入SuB-[”&Err.Number&“]:”&Err.Description
CurrentRun.Status=“失败”
CurrentTest.Status=“失败”
其他的
CurrentRun.Status=“Passed”需要函数来确定是否所有步骤都已通过
CurrentTest.Status=“Passed”需要函数来确定是否所有步骤都已通过
如果结束
如果结束
端接头
'**************************************************************************
'用于对所选项目执行SOAPUI的Sub
'**************************************************************************
'SOAPUITestRunner路径:TestRunner.bat文件
'项目位置:项目文件位置
'**************************************************************************
子调用APUIClient(soapuiTestrunnerPath、projectLocation、Tsite、Tcase、resultsP、CurrentTest、CurrentRun)
'**************************************************************************
'从命令行执行SOAPUI
'输出测试值供参考-不需要
'**************************************************************************
t输出。打印“TSuite:”和TSuite
t输出。打印“Tcase:&Tcase”
t输出。打印“resultsP:”&resultsP
设置fileSystem=CreateObject(“Scripting.FileSystemObject”)
'**************************************************************************
'如果程序所在的主机上未安装SOAPUI,则引发错误
'已运行或提供的可执行bat文件路径不正确
'**************************************************************************
如果(不是fileSystem.FileExists(soapuiTestrunnerPath)),那么
呃,提高8分
Err.Description=“soapUI testrunner未找到:”+SOAPUITestRunner路径
如果结束
'**************************************************************************
'args将是您希望传递给TestRunner的选项
'有关选项的完整列表,请在命令提示符下使用
“别无选择
'**************************************************************************
暗args
“args=“-s”&chr(34)&TSuite&chr(34)&“-c”&chr(34)&TCase&chr(34)&Drpath=“&resultsP&”&r-a-I”&chr(34)&projectLocation&chr(34)&
args=“-s”&TSuite&“-c”&TCase&“-M-j-fxml-R test.XML-F”&resultsP&“-R-g-A-I”&chr(34)&projectLocation&chr(34)&”
运行soapuiTestrunnerPath,args,-1,true
端接头
'**************************************************************************
'用于将结果添加到QC的子项-父项t
'*******************************************************************
'Debug, CurrentTestSet, CurrentTest, CurrentRun
'Debug, CurrentTestSet, CurrentTSTest, CurrentRun
'**************************************************************************
Sub Test_Main(Debug, CurrentTestSet, CurrentTest, CurrentRun )
' *** VBScript Limitation ! ***
' "On Error Resume Next" statement suppresses run-time script errors.
' To handle run-time error in a right way, you need to put "If Err.Number <> 0 Then"
' after each line of code that can cause such a run-time error.

On Error Resume Next
'Clear output window
TDOutput.Clear

'**************************************************************************
' Define the path for SOAPUI executable bat file and Project xml
' Project xml contains the test case(s) that need to be executed
'**************************************************************************
Dim trPath 'Path to test runner bat file
Dim soapResults 'Result file generated by SoapUI Groovy Script
Dim projFP 'SoapUI Project File Path
Dim spath 'Result File - Currently not using
Dim tf 'Test Factory Object
Dim ts 'Test ID
Dim TSuite 'SoapUI Test Suite Name
Dim Tcase 'SoapUI Test Case Name
Dim resultsP 'SoapUI output Report Location - Currently Not using

projFP = "C:\SOME\FILE\PATH\soapui-project.xml"
spath = "C:\File.txt"
trPath = "C:\program files\SmartBear\SoapUI-Pro-4.5.2\bin\testrunner.bat"
soapResults = "C:\Groovy_Report\test1.txt"

'Strings for SoapUI Execution
TSuite="SOAPUI_TESTSUITE_NAME"
Tcase="SOAPUI_TESTCASE_NAME"
resultsP="C:\SoapResults\" & Tcase

Set tf = TDConnection.TestFactory

Set ts = tf.Item(Field("TS_TEST_ID"))

'**************************************************************************
' Invoke SOAPUI and execute the selected project
'**************************************************************************

invokeSOAPUIClient trPath, projFP, TSuite, Tcase, resultsP, CurrentTest, CurrentRun

'**************************************************************************
' Get the Results from the text file in to Run Steps of the test case
'**************************************************************************

'wait 1 second to allow for larger files to complete writing
TDOutput.Print "Start Wait 10"
XTools.Sleep 1000
TDOutput.Print "END Wait 10"

'Get Result file and write to run steps
getResultsToQC CurrentRun, soapResults

'**************************************************************************
' handle run-time errors
'**************************************************************************
If Not Debug Then
If Err.Number <> 0 Then
TDOutput.Print "Run-time error - Execute SOAPUI:Enter SuB - [" & Err.Number & "] : " & Err.Description
CurrentRun.Status = "Failed"
CurrentTest.Status = "Failed"
Else
CurrentRun.Status = "Passed" 'Need Function here to determine if all steps passed
CurrentTest.Status = "Passed" 'Need Function here to determine if all steps passed
End If
End If
End Sub

'**************************************************************************
' Sub for executing SOAPUI with the selected project
'**************************************************************************
' soapuiTestrunnerPath: TestRunner .bat file
' projectLocation: Project file location
'**************************************************************************

Sub invokeSOAPUIClient(soapuiTestrunnerPath, projectLocation, TSuite, Tcase, resultsP, CurrentTest, CurrentRun)
'**************************************************************************
' Execute SOAPUI from the command line
' Output Test Values for reference - Not Required
'**************************************************************************
TDOutput.Print "TSuite: " & TSuite
TDOutput.Print "Tcase: " & Tcase
TDOutput.Print "resultsP: " & resultsP

set fileSystem = CreateObject("Scripting.FileSystemObject")

'**************************************************************************
' Raise error if SOAPUI is not installed in the host where program is
' runned or if the path of executable bat file provided is not correct
'**************************************************************************

If ( not fileSystem.FileExists(soapuiTestrunnerPath)) then
Err.Raise 8
Err.Description = "soapUI testrunner not found: " + soapuiTestrunnerPath
End if

'**************************************************************************
'args will be the options that you wish to pass to the TestRunner
'for a full list of options call the test runner from the command prompt with
'no options
'**************************************************************************
Dim args
'args = "-s" & chr(34) & TSuite & chr(34) & " -c" & chr(34) & TCase & chr(34) & " -Drpath=" & resultsP & " -r -a -I "& chr(34) & projectLocation & chr(34) &""
args = "-s" & TSuite & " -c" & TCase & " -M -j -F XML -R test.xml -f " & resultsP & " -r -g -A -I "& chr(34) & projectLocation & chr(34) &""
XTools.run soapuiTestrunnerPath, args, -1, true
End Sub

'**************************************************************************
' Sub for Adding Results to QC - Parent to addRunData() function
' function will parse the result file generated by SoapUI Groovy Script &
' add the run details for the Soap UI test to the QC run
'**************************************************************************
' sFile: File path to Groovy Script Results "C:\Groovy_Report\test1.txt"
' Currently this value is HARD CODED
'**************************************************************************
sub getResultsToQC(CurrentRun, sFile)
Set objFS = CreateObject("Scripting.FileSystemObject")
'Create object for result file
Set objFile = objFS.GetFile(sFile)
'OPen Stream to read in file
Set ts = objFile.OpenAsTextStream(1,-2)
'Loop through file line by line
Do Until ts.AtEndOfStream
'Create string value for current line
strLine = ts.ReadLine
'TDOutput.Print strLine

'Split values based on delimiter (Set in groovy Script)
ArrSplit=Split(strLine, "|")
size = Ubound(ArrSplit)

'Determine action for array values
'Size = 6 is a report value that will have pass/fail
'Size <> 6 is a info value and will have status = N/A
if(size=6) Then
'StepName
sStepName = ArrSplit(1) & "-" & ArrSplit(2)

'Clean Step Status and determine pass/fail
sSplit = Split(ArrSplit(4),":")
sValue = Trim(sSplit(1))
if(sValue="VALID")Then
sStatus = "Passed"
Elseif (sValue="FAILED") then
sStatus = "Failed"
Else
sStatus = "N\A"
End If

'Step Description
sDescription = ArrSplit(5)

'Step Expected
sExpected = ArrSplit(3)

'Step Actual
sActual = Trim(ArrSplit(6))

'Add run result to current execution run
addRunData CurrentRun, sStepName, sStatus, sDescription, sExpected, sActual
else
'Added in case other options arise in the future
if(Trim(ArrSplit(0)) = "INFO") Then
sStepName = "INFO - " & ArrSplit(1)
sStatus = "N/A"
sDescription = ArrSplit(1)
sExpected = "N/A"
sActual = ArrSplit(2)
addRunData CurrentRun, sStepName, sStatus, sDescription, sExpected, sActual
End If
End if

Loop
ts.Close
end sub

'**************************************************************************
' Sub for adding Test Steps to the current run
' function will add the run details for the Soap UI test to the QC run
'**************************************************************************
' sStepName: Passed from getResultsToQC - String to display the step name
' sStatus: Passed from getResultsToQC - String to determine step status
' sDescription: Passed from getResultsToQC - String to describe step
' sExpected: Passed from getResultsToQC - String to show expected value
' sActual: Passed from getResultsToQC - String to show actual value
'**************************************************************************

Sub addRunData(CurrentRun, sStepName, sStatus, sDescription, sExpected, sActual )

Dim objRun
Set objRun = CurrentRun
'Create Step object and add values to Object array
Set objStep = objRun.StepFactory.AddItem(null)
objStep.Field("ST_STEP_NAME")= sStepName
objStep.Field("ST_STATUS") = sStatus
objStep.Field("ST_DESCRIPTION") = sDescription
objStep.Field("ST_EXPECTED") = sExpected
objStep.Field("ST_ACTUAL") = sActual
objStep.Post
Set objStep = Nothing

end sub
import jxl.*
import jxl.write.*
import java.lang.*
import com.eviware.soapui.support.XmlHolder
//*********************************************************************
//Define Array to hold reporting data
//*********************************************************************
def reportInfo = []
//*********************************************************************
//Define test name
//*********************************************************************
def testName= testRunner.testCase.name.toString()
def fpath = context.expand( '${projectDir}' )
def tcase = testRunner.testCase
//*********************************************************************
//Get number of Test steps
//*********************************************************************
def size = testRunner.testCase.getTestStepCount();
//*********************************************************************
//loop through test steps
//*********************************************************************
for(int i = 0; i<size; i++){
//*********************************************************************
//get Step Name
//*********************************************************************
name = tcase.getTestStepAt(i).getName()

//*********************************************************************
//create test step object
//*********************************************************************
testStep = testRunner.getTestCase().getTestStepByName(“$name”)
//*********************************************************************
//Get test step type
//*********************************************************************
def stepType = testStep.config.type
//*********************************************************************
//Determine course of action for each step type
//*********************************************************************
if(stepType==”datasink”){
//*********************************************************************
//Info Step as we won’t be running assertions on this step type
//Data will be added to reportInfo Array
//*********************************************************************
def info = “INFO | Data Sink Step | “+name
reportInfo << info
}else if(stepType==”groovy”){
//*********************************************************************
//Info Step as we won’t be running assertions on this step type
//Data will be added to reportInfo Array
//*********************************************************************
def info = “INFO | Groovy Script Step | “+name
reportInfo << info
}else if(stepType==”request”){
//*********************************************************************
//Report Step as we WILL be running assertions on this step type
//Data will be added to reportInfo Array
//*********************************************************************
//Create List of Assertion names, Counter == alist Size, and
//Assertion status
//*********************************************************************
def assertionNameList = testStep.getAssertionList().name
def counter = assertionNameList.size()
def assertionStatus = testStep.getAssertionList()
//*********************************************************************
//Loop through assertionList
//*********************************************************************
for(j=0;j<counter;j++)
{
def iAssertionName = assertionNameList[j]
def iAssertionStatus = testStep.getAssertionAt(j).getStatus().toString()
def tstep = testStep.getName()
if(iAssertionName==”SOAP Response”){
//*********************************************************************
//If Assertion type is SOAP Response Capture Step Status and XML
//*********************************************************************
def response = context.expand( ‘${‘+tstep+’#Response}’ )
response = response.replace(“\n”, “”)
response = response.replace(“\r”, “”)
def type = testStep.getAssertionAt(j).config.type
def reportString = “Report | ” + tstep + ” | ” + iAssertionName + ” | Expected Success Response |” + “Status: ” + iAssertionStatus + ” | ” + type + ” | ” + response
log.info reportString
reportInfo << reportString
}else{
//*********************************************************************
//If Assertion type is NOT SOAP Response Capture:
// Step Status
// Expected Value
// Assertion Type
// Actual (If Error=Error Message Else = Expected)
//*********************************************************************
def expect = testStep.getAssertionAt(j).expectedContent
def expectedValue = context.expand(expect)
def gStatus = testStep.getAssertionAt(j).status
gStatus = gStatus.toString()
def gAssert = testStep.getAssertionAt(j)
def gType = testStep.getAssertionAt(j).config.type
if(gStatus!=’FAILED’){
def reportString = “Report | ” + tstep + ” | ” + iAssertionName + ” | Expected: ” + expectedValue + “|” + ” Status: ” + gStatus + “|” + ” Type: ” + gType + “|” + expectedValue
log.info reportString
reportInfo << reportString
}else{
for( e in testStep.getAssertionAt(j).errors ){
def reportString = “Report | ” + tstep + ” | ” + iAssertionName + ” | Expected: ” + expectedValue + “|” + ” Status: ” + gStatus + “|” + ” Type: ” + gType + “|” + ” Error [" + e.message + "]”
log.info reportString
reportInfo << reportString
}
}

}
}
}else{
//*********************************************************************
//We will want to log a message for this step
//for currently unhandled step types
//*********************************************************************
}
}
//*********************************************************************
//capture execution time
//*********************************************************************
def gTimeInfo = “INFO | TIME | “+testRunner.getTimeTaken()
reportInfo << gTimeInfo
log.info gTimeInfo
//*********************************************************************
//create report for test
//*********************************************************************
//Folder within directory to save results to. If folder does not exist
//we will create it
//*********************************************************************
def folder = “Groovy_Report”
//*********************************************************************
//Directory to place create folder in or location of Folder
//*********************************************************************
def dir = “c:/”
//*********************************************************************
//Define and execute folder creation method
//*********************************************************************
def c
c = createFolder(dir,folder)
//*********************************************************************
//Define test file name and create report file
//*********************************************************************
def fName = “test1″
createfile(c,”fName”,”.txt”,reportInfo)
//*********************************************************************
//Create File Method
//*********************************************************************
//Input:
// dir: root folder directory
// filenm: name of file to be created minus the extension
// ext: file extension to be used
// info: array of strings containing your file data
//*********************************************************************
public void createfile(def dir, def filenm, def ext, def info){
new File(“$dir/$filenm$ext”).withWriter { out ->
info.each {
out.println it
}
}
}
//*********************************************************************
//Create File Method
//*********************************************************************
//Input:
// dir: root folder directory
// folder: folder to add to directory
//Output:
// String: directory root for file creation
//*********************************************************************
public String createFolder(def dir,def folder){
File f = new File(“$dir/$folder”);
f.mkdirs();
return “$dir/$folder”
}