I have a requirement to write a results (Pass/Fail) in the same excel sheet where the script reads the parameter in a FOR loop. It is throwing an error:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'jxl.read.biff.WorkbookParser#3da0525b' with class 'jxl.read.biff.WorkbookParser' to class 'jxl.write.WritableWorkbook' error at line: 16
My code:
import jxl.*;
import jxl.write.*;
import java.io.*;
import groovy.json.JsonSlurper
//Get project path
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def projectPath = groovyUtils.projectPath
def testCaseName = testRunner.testCase.name
//Read excel file and get the input value
WritableWorkbook xlwb = Workbook.getWorkbook(new File ("${projectPath}\\${testCaseName}.xls"))
Sheet inputxlsh = xlwb.getSheet(0)
inputRowCount = inputxlsh.getRows();
WritableSheet outputxlsh = xlwb.getSheet(1)
outputRowCount = outputxlsh.getRows();
log.info "Executing Test Case " + testCaseName
log.info "Total records to send API request to webservice from the file : " + inputRowCount -1
for (i=0;i<inputRowCount-1;i++)
{
Cell requestParam1 = inputxlsh.getCell(0,i+1)
affkey = requestParam1.getContents()
Cell requestParam2 = inputxlsh.getCell(1,i+1)
etid = requestParam2.getContents()
def soapTestCase = context.testCase
//Set the request property value (Parameter)
requestPropertyVariable = soapTestCase.getTestStepByName("requestProperty")
requestPropertyVariable.setPropertyValue("affkey",affkey)
requestPropertyVariable.setPropertyValue("etid",etid)
log.info "Reading record " + (i+1) + " from input file"
log.info "Sending request with affkey " + affkey
log.info "Sending request with etid " + etid
//Post a request to webservice
def responseContent = testRunner.runTestStepByName("showetidRequest").getResponse()
def responseText = responseContent.getContentAsString()
//Save the output file
def fileObj = new File("${projectPath}\\API_Response\\${testRunner.testCase.name}\\${etid}_Response.txt")
saveToFile(fileObj, responseText)
//Get the response value
JsonSlurper jsonResponseContent = new JsonSlurper()
def jsonResponseObject = jsonResponseContent.parseText(responseText)
//Validate results
Cell headerParam1 = outputxlsh.getCell(0,0)
Cell headerParam2 = outputxlsh.getCell(1,0)
Cell headerParam3 = outputxlsh.getCell(2,0)
Cell headerParam4 = outputxlsh.getCell(3,0)
Cell headerParam5 = outputxlsh.getCell(4,0)
Cell headerParam6 = outputxlsh.getCell(5,0)
for (k = 0; k < outputRowCount-1; k++) {
Cell responseParam1 = outputxlsh.getCell(0,k+1)
Cell responseParam2 = outputxlsh.getCell(1,k+1)
Cell responseParam3 = outputxlsh.getCell(2,k+1)
Cell responseParam4 = outputxlsh.getCell(3,k+1)
Cell responseParam5 = outputxlsh.getCell(4,k+1)
Cell responseParam6 = outputxlsh.getCell(5,k+1)
expectedAffiliatesWithContent = responseParam1.getContents()
expectedEntityName = responseParam2.getContents()
expectedName = responseParam3.getContents()
expectedSaleMessageId = responseParam4.getContents()
expectedTitle = responseParam5.getContents()
expectedetid = responseParam6.getContents()
if(etid==expectedetid){
responseAffiliatesWithContent = jsonResponseObject.AffiliatesWithContent.getAt(0).getAt(0)
responseEntityName = jsonResponseObject.Genre.EntityName.getAt(0)
responseName = jsonResponseObject.Genre.Name.getAt(0)
responseSaleMessageId = jsonResponseObject.SaleMessage.Id.getAt(0)
responseTitle = jsonResponseObject.Title.getAt(0)
log.info responseAffiliatesWithContent
log.info responseEntityName
log.info responseName
log.info responseSaleMessageId
log.info responseTitle
if (responseAffiliatesWithContent==expectedAffiliatesWithContent&&responseEntityName==expectedEntityName&&responseName==expectedName&&responseSaleMessageId==expectedSaleMessageId&&
responseTitle==expectedTitle)
{
log.info "The data is matched for record " + (k +1) + " hence test case passed "
Label l = new Label(7, k +1, "Pass");
outputxlsh.addCell(l);
xlwb.write();
}
else {
log.info "The data is matched for record " + (k +1) + " hence test case failed "
}
}
}
}
//Clear Property
requestPropertyVariable.setPropertyValue("affkey","")
requestPropertyVariable.setPropertyValue("etid","")
//Write file method
def saveToFile(fileObj, content) {
if (!fileObj.parentFile.exists()) {
fileObj.parentFile.mkdirs()
}
fileObj.write(content)
log.info "Response for etid " + etid + " is stored in " + "${etid}_Response.txt"
assert fileObj.exists(), "${fileObj.name} not created"
}
If you want a write able copy call createWorkbook function
WritableWorkbook xlwb = Workbook.createWorkbook(new File ("${projectPath}\\${testCaseName}.xls"))
If you don't want write able copy save in Workbook object instead
Workbook workbook = Workbook.getWorkbook((new File ("${projectPath}\\${testCaseName}.xls"))
I have achieved the requirement based on below code
def inptDataWb = new HSSFWorkbook(xlwb);
def inputxlsh = inptDataWb.getSheetAt(2);
wrtResult = outputxlsh.getRow(k+1).getCell(3);
wrtResult.setCellValue("P");
wrtResult = outputxlsh.getRow(k+1).getCell(5);
wrtResult.setCellValue("");
inptDataWb.write(xlOwb);
Related
I am new to coding, below is a groovy script that I am using in Soap UI to dump response data into an excel sheet. I am getting error at line 55, '}' for closing if condition (which I believe is not the issue). Earlier I was using only jexl and it was working fine but then I switched to poi to be able to append data in same sheet and it throws error. I have already copied all the relevant jars in bin/ext.
import java.io.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.*;
import jxl.*;
def grUtils = new com.eviware.soapui.support.GroovyUtils(context)
def ReqHolder = grUtils.getXmlHolder("Search#Response")
def HotelCount = ReqHolder["count(//*:Property)"]
def tCNo = context.expand( '${DSS#TCNo.}' )
if (tCNo =='1')
{
FileInputStream fsIP= new FileInputStream(new File("C:/Users/129858/Desktop/Soap/Simplify_HTE/SearchSink.xls"));
HSSFWorkbook copy = new HSSFWorkbook(fsIP);
HSSFSheet worksheet = copy.getSheetAt(0);
CL = 0;
rows = HotelCount.toInteger();
Cell cell = null;
cell = worksheet.getRow(0).getCell(0);
cell.setCellValue("TCNo.");
cell = worksheet.getRow(0).getCell(1);
cell.setCellValue("HotelName");
cell = worksheet.getRow(0).getCell(2);
cell.setCellValue("HotelCode");
cell = worksheet.getRow(0).getCell(3);
cell.setCellValue("BrandCode");
for( tc_row in 1..rows){
Cell box = null;
cell = worksheet.getRow(tc_row).getCell(CL);
String s0 = tCNo;
cell.setCellValue(s1);
cell = worksheet.getRow(tc_row).getCell(CL+1);
String s1 = ReqHolder.getNodeValue("//*:Property[$tc_row]/#HotelName");
cell.setCellValue(s1);
cell = worksheet.getRow(tc_row).getCell(CL+2);
String s2 = ReqHolder.getNodeValue("//*:Property[$tc_row]/#HotelCode");
cell.setCellValue(s2);
cell = worksheet.getRow(tc_row).getCell(CL+3);
String s3 = ReqHolder.getNodeValue("//*:Property[$tc_row]/#BrandCode");
cell.setCellValue(s3);
}
fsIP.close();
FileOutputStream fsOP =new FileOutputStream(new File("C:/Users/129858/Desktop/Soap/Simplify_HTE/SearchSink.xls");
copy.write(fsOP);
fsOP.close();
}
else{
FileInputStream file = new File("C:/Users/129858/Desktop/Soap/Simplify_HTE/SearchSink.xls");
HSSFWorkbook wb = new HSSFWorkbook(file);
HSSFsheet ws = wb.getSheetAt(0):
datarows = ws.getRows();
col = 0;
log.info datarows
exrows = HotelCount.toInteger() + datarows + 1;
log.info exrows
for( tc_ro in datarows+1..exrows)
{
Cell box = null;
cell = worksheet.getRow(tc_ro).getCell(col);
String s0 = tCNo;
cell.setCellValue(s1);
cell = worksheet.getRow(tc_ro).getCell(col+1);
String s1 = ReqHolder.getNodeValue("//*:Property[$tc_row]/#HotelName");
cell.setCellValue(s1);
cell = worksheet.getRow(tc_ro).getCell(col+2);
String s2 = ReqHolder.getNodeValue("//*:Property[$tc_row]/#HotelCode");
cell.setCellValue(s2);
cell = worksheet.getRow(tc_ro).getCell(col+3);
String s3 = ReqHolder.getNodeValue("//*:Property[$tc_row]/#BrandCode");
cell.setCellValue(s3);
}
fsIP.close();
FileOutputStream fsOP =new FileOutputStream(new File("C:/Users/129858/Desktop/Soap/Simplify_HTE/SearchSink.xls");
copy.write(fsOP);
fsOP.close();
}
In line 53 you are missing one closing bracket:
FileOutputStream fsOP =new FileOutputStream(new File("C:/Users/129858/Desktop/Soap/Simplify_HTE/SearchSink.xls");
It should be:
FileOutputStream fsOP =new FileOutputStream(new File("C:/Users/129858/Desktop/Soap/Simplify_HTE/SearchSink.xls"));
The same thing happens in line 91.
Consider using an editor with code validation and completion. You can choose from wide range of free to use IDE's like IntelliJ IDEA, Eclipse, Netbeans and so on. IDEA for instance would quickly tell you that you are missing this closing bracket and you would save a lot of time.
Thanks Stepniak, for pointing me in the right direction. It had way too many errors and some really crappy codding. Its working fine now.
import java.io.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.*;
import jxl.*;
def grUtils = new com.eviware.soapui.support.GroovyUtils(context)
def ReqHolder = grUtils.getXmlHolder("Search#Response")
def HotelCount = ReqHolder["count(//*:Property)"]
def tCNo = context.expand( '${DSS#TCNo.}' )
if (tCNo =='1')
{
HSSFWorkbook copy = new HSSFWorkbook();
HSSFSheet worksheet = copy.createSheet("SearchSink");
CL = 0;
rows = HotelCount.toInteger();
Row head = worksheet.createRow(0);
Cell cell0 = head.createCell(0);
cell0.setCellValue("TCNo.");
Cell cell1 = head.createCell(1);
cell1.setCellValue("HotelName");
Cell cell2 = head.createCell(2);
cell2.setCellValue("HotelCode");
Cell cell3 = head.createCell(3);
cell3.setCellValue("BrandCode");
for( tc_row in 1..rows){
Row data = worksheet.createRow(tc_row);
Cell box0 = data.createCell(CL);
String s0 = tCNo;
box0.setCellValue(s0);
Cell box1 = data.createCell(CL+1);
String s1 = ReqHolder.getNodeValue("//*:Property[$tc_row]/#HotelName");
box1.setCellValue(s1);
Cell box2 = data.createCell(CL+2);
String s2 = ReqHolder.getNodeValue("//*:Property[$tc_row]/#HotelCode");
box2.setCellValue(s2);
Cell box3 = data.createCell(CL+3);
String s3 = ReqHolder.getNodeValue("//*:Property[$tc_row]/#BrandCode");
box3.setCellValue(s3);
}
FileOutputStream fsOP =new FileOutputStream(new
File("C:/Users/129858/Desktop/Soap/Simplify_HTE/SearchSink.xls"));
copy.write(fsOP);
fsOP.close();
}
else{
FileInputStream file = new FileInputStream(new
File("C:/Users/129858/Desktop/Soap/Simplify_HTE/SearchSink.xls"));
HSSFWorkbook wb = new HSSFWorkbook(file);
HSSFSheet ws = wb.getSheetAt(0);
int datarows = ws.getLastRowNum();
col = 0;
log.info datarows
exrows = HotelCount.toInteger() + datarows;
log.info exrows
for( tc_ro in datarows+1..exrows)
{
Row data = ws.createRow(tc_ro);
Cell box0 = data.createCell(col);
String s0 = tCNo;
box0.setCellValue(s0);
Cell box1 = data.createCell(col+1);
String s1 = ReqHolder.getNodeValue("//*:Property[$tc_ro-$datarows]/#HotelName");
box1.setCellValue(s1);
Cell box2 = data.createCell(col+2);
String s2 = ReqHolder.getNodeValue("//*:Property[$tc_ro-$datarows]/#HotelCode");
box2.setCellValue(s2);
Cell box3 = data.createCell(col+3);
String s3 = ReqHolder.getNodeValue("//*:Property[$tc_ro-$datarows]/#BrandCode");
box3.setCellValue(s3);
}
file.close();
FileOutputStream fsOP =new FileOutputStream(new
File("C:/Users/129858/Desktop/Soap/Simplify_HTE/SearchSink.xls"));
wb.write(fsOP);
fsOP.close();
}
I am trying to copy multiple rows from an excel sheet with a Groovy Script, but somehow I am hitting the java.lang.NullPointerException error. The code I am using is the following:
import com.eviware.soapui.support.XmlHolder
import jxl.*
import jxl.write.*
def numofapps = context.expand('${Data_AppNM#NumberOfApplicants}')
def apps2 = ["2","3","4","5","6"]
def myTestCase = context.testCase
def counter,next,previous,size
Workbook workbook1 = Workbook.getWorkbook(new File("C://Path//Multiple records.xls"))
Sheet sheet1 = workbook1.getSheet(0)
size= sheet1.getRows().toInteger()
propTestStep = myTestCase.getTestStepByName("Data")
propTestStep.setPropertyValue("Total", size.toString())
counter = propTestStep.getPropertyValue("Count").toString()
counter = counter.toInteger()
next = (counter > size-2? 0: counter+1)
Cell u1_1 = sheet1.getCell(0,counter)
Cell u2_1 = sheet1.getCell(1,counter)
Cell u3_1 = sheet1.getCell(2,counter)
workbook1.close()
1value1 = u1_1.getContents()
2value1 = u2_1.getContents()
3value1 = u3_1.getContents()
propTestStep.setPropertyValue("A1.1Value", 1value1 )
propTestStep.setPropertyValue("A1.2Value", 2value1 )
propTestStep.setPropertyValue("A1.3Value", 3value1 )
propTestStep.setPropertyValue("Count", next.toString())
next++ //increase next value
propTestStep.setPropertyValue("Next", next.toString())
if (apps2.contains(numofapps)){ //setting values for Applicant 2 if requested
counter = propTestStep.getPropertyValue("Count").toString()
counter = counter.toInteger()
next = (counter > size-2? 0: counter+1)
// Extracting the Data from the Excel sheet
Cell u1_2 = sheet1.getCell(0,counter)
Cell u2_2 = sheet1.getCell(1,counter)
Cell u3_2 = sheet1.getCell(2,counter)
workbook1.close()
1value2 = u1_2.getContents()
2value2 = u2_2.getContents()
3value2 = u3_2.getContents()
propTestStep.setPropertyValue("A2.1Value", 1value2 )
propTestStep.setPropertyValue("A2.2Value", 2value2 )
propTestStep.setPropertyValue("A2.3Value", 3value2 )
propTestStep.setPropertyValue("Count", next.toString())
next++ //increase next value
propTestStep.setPropertyValue("Next", next.toString())
}
I am hitting the NullPointerException error on the Cell u1_2 = sheet1.getCell(0,counter) step.
Can you please tell me why I am hitting these and is there any other way that I can use a shorter code?
Thank you :)
I'm gonna include the xml structure below:
#Rao, #tim_yates. The actual xml is:
<prnReq>
<ltrPrnReqs>
<ltrPrnReq>
<ltrData>encoded64 text</ltrData>
</ltrPrnReq>
</ltrPrnReqs>
</prnReq>
I need to include a new Node in . The new XML must be:
<prnReq>
<ltrPrnReqs>
<ltrPrnReq>
<ltrData>
<Salutation>text</Salutation>
</ltrData>
</ltrPrnReq>
</ltrPrnReqs>
</prnReq>
The question is how to append a new node in ?
I've found many samples how to use appendNode, however, it is always a
root.child. I need to go further in my XML structure and append a node at
prnReq.ltrPrnReqs.ltrPrnReq.ltrData
the node to be included is <salutation>
Any comments are welcome.
Below the current code.
Many thanks!
import groovy.xml.QName
import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil
File doc = new File("C:/Temp/letter_.xml")
def prnReq = new XmlSlurper().parse(doc)
prnReq.ltrPrnReqs.ltrPrnReq.each {
def encodedString = it.ltrData.toString()
Base64.Decoder decoder = Base64.getMimeDecoder()
byte[] decodedByteArray = decoder.decode(encodedString)
def output = new String(decodedByteArray)
println output
output.splitEachLine(';') { items ->
println "raSalutation: " + items[0]
println "raFromAcc: " + items[1]
println "raPayableTo: " + items[2]
println "raSortCode: " + items[3]
println "raAccNum: " + items[4]
println "raReference: " + items[5]
println "raSendDate: " + items[6]
println "raRecDate: " + items[7]
println "raAmount: " + items[8]
println "raDummy1: " + items[9]
println "raFirstAmt: " + items[10]
println "raFirstDate: " + items[11]
println "raRegularAmt: " + items[12]
println "raRegularDate: " + items[13]
println "raFrequency: " + items[14]
println "raFee: " + items[15]
def toAdd = '"<salutation>$item[0]</salutation>"'
fragToAdd = new XmlSlurper().parseText(toAdd)
prnReq.ltrPrnReqs.ltrPrnReq.ltrData.appendNode(fragToAdd)
}
String outputFileName = "C:/Temp/letter_.xml"
XmlUtil xmlUtil = new XmlUtil()
xmlUtil.serialize(prnReq, new FileWriter(new File(outputFileName)))
}
You should be able to add the new node using appendNode.
Here is complete sample showing how to do it.
def xmlString = """<prnReq>
<ltrPrnReqs>
<ltrPrnReq>
<ltrData>encoded64 text</ltrData>
</ltrPrnReq>
</ltrPrnReqs>
</prnReq>"""
def xml = new XmlSlurper().parseText(xmlString)
def ltrData = xml.'**'.find{it.name() == 'ltrData'}
ltrData.replaceBody()
ltrData.appendNode {
Salutation('text')
}
println groovy.xml.XmlUtil.serialize(xml)
You can quickly try it online demo
I have a SOAP request which has dynamic values generated by random method. How to capture these generated values to log?
My SOAP request:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://www.webserviceX.NET/">
<soap:Header/>
<soap:Body>
<web:ChangeLengthUnit>
<web:LengthValue>${=(int)(Math.random()*9999)}</web:LengthValue>
<web:fromLengthUnit>Inches</web:fromLengthUnit>
<web:toLengthUnit>Centimeters</web:toLengthUnit>
</web:ChangeLengthUnit>
</soap:Body>
</soap:Envelope>
Groovy script:
import com.eviware.soapui.support.GroovyUtils;
def prj = testRunner.testCase.testSuite.project.workspace.getProjectByName("Project1")
tCase = prj.testSuites['TestSuite'].testCases['TestCase']
tStep = tCase.getTestStepByName("ChangeLengthUnit")
def stepReq = tStep.getProperty("Request").getValue()
def runner = tStep.run(testRunner, context)
log.info ("runner status ....... : " + runner.hasResponse())
log.info stepReq
for( assertion in tStep.assertionList )
{
log.info "Assertion [" + assertion.label + "] has status [" + assertion.status + "]"
for( e in assertion.errors )
log.info "-> Error [" + e.message + "]"
}
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def holder = groovyUtils.getXmlHolder( stepReq.toString() )
log.info holder.getNodeValues( "//web:LengthValue" ).toString()
Above groovy script is giving output as below:
Wed Oct 18 14:55:13 SGT 2017:INFO:[${=(int)(Math.random()*9999)}]
Actual value of LengthValue tag = 3490, How to get this value ?
It can easily read from RawRequest property using Script Assertion for the same request step.
assert context.rawRequest, 'Request is empty or null'
def xml = new XmlSlurper().parseText(context.rawRequest)
def actualValueInTheRequest = xml.'**'.find{it.name() == 'LengthValue'}?.text()
log.info "Value for LengthValue in the actual request is : $actualValueInTheRequest"
I think what you're doing is getting the LengthValue from the request 'template' not what SoapUI has actually passed to the web service.
In your example, you have...
def stepReq = tStep.getProperty("Request").getValue()
The request is what you see in SoapUI that includes your vars, e.g. ${myVar}. I think what you're after is the 'raw request'.
In SoapUI, run the request and after it has ran, you should see a tab labelled 'Raw Request'. This is what SoapUI actually sends to the web service, in here you'll see that the vars have been evaluated and will show the value, which is what you are after.
I've taken your example and made some mods it. I haven't tested it, but it should help you.
import com.eviware.soapui.support.GroovyUtils;
def prj = testRunner.testCase.testSuite.project.workspace.getProjectByName("Project1")
tCase = prj.testSuites['TestSuite'].testCases['TestCase']
tStep = tCase.getTestStepByName("ChangeLengthUnit")
def stepReq = tStep.getProperty("Request").getValue()
def runner = tStep.run(testRunner, context)
// CHA MOD - Can only get raw request after running the step.
def rawRequest = context.expand( '${ChangeLengthUnit#RawRequest}' )
//CHA MOD - Quick look at the rawRequest...
log.info(rawRequest);
log.info ("runner status ....... : " + runner.hasResponse())
log.info stepReq
for( assertion in tStep.assertionList )
{
log.info "Assertion [" + assertion.label + "] has status [" + assertion.status + "]"
for( e in assertion.errors )
log.info "-> Error [" + e.message + "]"
}
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def holder = groovyUtils.getXmlHolder( stepReq.toString() )
log.info holder.getNodeValues( "//web:LengthValue" ).toString()
//CHA MOD - Get the length from the raw request...
holder = groovyUtils.getXmlHolder( rawRequest.toString() )
log.info holder.getNodeValues( "//web:LengthValue" ).toString()
You are getting value from the actual request. Try to get the data from RawRequest
use below code
def holder = groovyUtils.getXmlHolder(mentionThenameofthestep#RawRequest)
The above code will point to Raw request of your teststep which contains actual value passed during execution instead of "${=(int)(Math.random()*9999)}"
I had a scenario where I need to add my test results from a SoapUI test case to a related test case in HP Quality Center. How could I go about doing this with Groovy.
Quality Center offers an OTA API to interface with it; however, it is written to use the Microsoft COM structure which Java/Groovy has no native way to consume. Lucky, there is a Groovy library, Scriptom, that allows Groovy to consume COM interfaces.
After getting every setup, this is the sample code that I came up with:
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()
}
I had issues with the scriptom and being new to Groovy but having experience with Quality Center I wrote a tear down script for my SoapUI test that writes my results to a flat file and then I use the VBScript to pull the data in.
These scripts use hard coded values but hopefully will get you started:
VAPI-XP Script - http://ryanoglesby.net/2013/08/23/executing-soapui-from-quality-center-part-1/
'*******************************************************************
'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
Groovy SoapUI TearDown Script - http://ryanoglesby.net/2013/08/28/executing-soapui-from-quality-center-part-2-groovy-teardown-script/
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”
}