Loop test steps in multiple test cases using SOAPUI - groovy

I'm having some issue in automating web services.
Actually I have an excel sheet containing all the input and outputs needed.
I wrote a groovy script that retrieve inputs, save them in properties, execute query, retrieve outputs and compare them with excel outputs.
My problem is that all the process is execute as one test case.
I want to "pimp" my process so that every line of my Excel sheet is dealt as a test case.
Here's the groovy code :
import jxl.*
import jxl.write.*
Workbook workbook1 = Workbook.getWorkbook(new File("C:\\Users\\****\\Desktop\\GroovyPSSheet.xls"))
Sheet sheet1 = workbook1.getSheet(0)
for (int i=6; i<sheet1.getRows(); i++)
{
sleep 1000
if (sheet1.getCell(0,i).getContents()=="")
{
i++
}
Cell clairance = sheet1.getCell(3,i)
Cell etatpatho = sheet1.getCell(2,i)
Cell idlReq = sheet1.getCell(1,i)
Cell idprod = sheet1.getCell(0,i)
Cell typeprod = sheet1.getCell(4,i)
testRunner.testCase.setPropertyValue( "clairance", clairance.getContents() )
testRunner.testCase.setPropertyValue( "etatpatho", etatpatho.getContents() )
testRunner.testCase.setPropertyValue( "idlReq", idlReq.getContents() )
testRunner.testCase.setPropertyValue( "idprod", idprod.getContents() )
testRunner.testCase.setPropertyValue( "typeprod", typeprod.getContents() )
sleep 500
def ExecuteQuery = testRunner.testCase.testSteps['ExecuteQuery']
ExecuteQuery.run( testRunner, context )
sleep 1000
groovyUtils = new com.eviware.soapui.support.GroovyUtils(context )
holder = groovyUtils.getXmlHolder ("ExecuteQuery#Response")
id_type_alerte = holder.getNodeValue("//id_type_alerte")
testRunner.testCase.setPropertyValue( "id_type_alerte", sheet1.getCell(5,i).getContents() )
idproduit = holder.getNodeValue("//idproduit")
testRunner.testCase.setPropertyValue( "idproduit", sheet1.getCell(6,i).getContents() )
typeproduit = holder.getNodeValue("//typeproduit")
testRunner.testCase.setPropertyValue( "typeproduit", sheet1.getCell(7,i).getContents() )
id_ter_per = holder.getNodeValue("//id_ter_per")
testRunner.testCase.setPropertyValue( "id_ter_per", sheet1.getCell(8,i).getContents() )
lib_ter_per = holder.getNodeValue("//lib_ter_per")
testRunner.testCase.setPropertyValue( "lib_ter_per", sheet1.getCell(9,i).getContents() )
id_ter_com = holder.getNodeValue("//id_ter_com")
testRunner.testCase.setPropertyValue( "id_ter_com",sheet1.getCell(10,i).getContents() )
id_typ_ter = holder.getNodeValue("//id_typ_ter")
testRunner.testCase.setPropertyValue( "id_typ_ter", sheet1.getCell(11,i).getContents() )
lib_ter = holder.getNodeValue("//lib_ter")
testRunner.testCase.setPropertyValue( "lib_ter", sheet1.getCell(12,i).getContents() )
id_nature_ci = holder.getNodeValue("//id_nature_ci")
testRunner.testCase.setPropertyValue( "id_nature_ci", sheet1.getCell(13,i).getContents() )
id_ter = holder.getNodeValue("//id_ter")
testRunner.testCase.setPropertyValue( "id_ter", sheet1.getCell(14,i).getContents() )
id_sequence_ter = holder.getNodeValue("//id_sequence_ter")
testRunner.testCase.setPropertyValue( "id_sequence_ter", sheet1.getCell(15,i).getContents() )
id_fic_ci = holder.getNodeValue("//id_fic_ci")
testRunner.testCase.setPropertyValue( "id_fic_ci", sheet1.getCell(16,i).getContents() )
sleep 1000
}
workbook1.close()
Thanks !

Seems that you want to get a next testCase from the current testSuite for each row in the your datasheet instead of performing the operation in the current testCase each time. I'm not sure that this is your goal, but you can collect all the testCases from the current testSuite and select the next one for each row, something like this can do the trick:
// get all testCases from the current testSuite as List
def allTestCases = testRunner.testCase.testSuite.testCases.collect{ name, testCase ->
return testCase
}
// row iteration
for (int i=6; i<sheet1.getRows(); i++)
{
// get a testCase
def testCase = allTestCases.take(1);
// drop the element from the list to change next iteration
allTestCases = allTestCases.drop(1);
...
...
// in the rest of your code use the testCase variable from the list
// instead of using testRunner.testCase which always take the current one
testCase.setPropertyValue("clairance", clairance.getContents())
testCase.setPropertyValue("etatpatho", etatpatho.getContents())
...
def ExecuteQuery = testCase.testSteps['ExecuteQuery']
ExecuteQuery.run( testRunner, context )
...
}
Hope it helps,

Related

Groovy Script hangs while fetching 22k rows

I am using a Groovy script to fetch data from excel data source for SOAP UI request message. Script works till 100 rows beyond that it hang and goes to unresponsive in soap ui.
This groovy script works in SOAP UI for 50 records in excel but I need to use excel which has 22k rows.
This is the complete hierarchy of the groovy script:-
https://www.belatrixsf.com/blog/trick-for-soapui-free-in-eight-steps/
// IMPORT THE LIBRARIES WE NEED
import com.eviware.soapui.support.XmlHolder
import jxl.*
import jxl.write.*
// DECLARE THE VARIABLES
def myTestCase = context.testCase //myTestCase contains the test case
def counter,next,previous,size //Variables used to handle the loop and to move inside the file
Workbook workbook1 = Workbook.getWorkbook(new File("c:\\dataFile.xls")) //file containing the data
Sheet sheet1 = workbook1.getSheet(0) //save the first sheet in sheet1
size= sheet1.getRows().toInteger() //get the number of rows, each row is a data set
propTestStep = myTestCase.getTestStepByName("Property - Looper") // get the Property TestStep object
propTestStep.setPropertyValue("Total", size.toString())
counter = propTestStep.getPropertyValue("Count").toString() //counter variable contains iteration number
counter = counter.toInteger() //
next = (counter > size-2? 0: counter+1) //set the next value
// OBTAINING THE DATA YOU NEED
Cell u = sheet1.getCell(0,counter) // getCell(column,row) //obtains user
Cell p = sheet1.getCell(1,counter) // obtains password
workbook1.close() //close the file
////////////////////////////////////
usr = u.getContents()
pass = p.getContents()
propTestStep.setPropertyValue("user", usr) //the value is saved in the property
propTestStep.setPropertyValue("pass", pass) //the value is saved in the property
propTestStep.setPropertyValue("Count", next.toString()) //increase Count value
next++ //increase next value
propTestStep.setPropertyValue("Next", next.toString()) //set Next value on the properties step
//Decide if the test has to be run again or not
if (counter == size-1)
{
propTestStep.setPropertyValue("StopLoop", "T")
log.info "Setting the stoploop property now..."
}
else if (counter==0)
{
def runner = new com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner(testRunner.testCase, null)
propTestStep.setPropertyValue("StopLoop", "F")
}
else
{
propTestStep.setPropertyValue("StopLoop", "F")
}
Expected output groovy script should not hang while fetching 22k records from excel.

How to use Groovy script in soapUi to loop multiple time

I am new to SoapUi. I am exploring on how multiple request in soapUi is done using groovy script.
below is the example that im trying to do, based on example that i found through "googling"
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.model.testsuite.*;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner
import java.util.Random
import com.eviware.soapui.model.testsuite.TestRunner.Status
// Define your testCase pointer
//def testcase = testRunner.testCase.testSuite.project.testSuites["TestSuite - User Management REST API"].getTestCaseByName ("Authenticate User")
def counterUser = testRunner.testCase.testSuite.getPropertyValue( "counter" )
int value = counterUser.toInteger()
String tester = ""
30.times {
value = value + 1
tester = "tester " + value.toString()
testRunner.testCase.testSuite.setPropertyValue( "userName", tester )
testRunner.runTestStepByName("POST - createUser - Create a User")
}
testRunner.testCase.testSuite.setPropertyValue( "counter", value.toString() )
I want to create a 30 users which start from Tester1...tester2.....tester30.
Is it possible to do this way? I keep getting an error such as NullPointerException at this line
int value = counterUser.toInteger()
I got what you say.
That is because, initially there is no value for counter which results to null and you are applying toInteger() over it.
Just change:
From:
int value = counterUser.toInteger()
To:
int value = counterUser?.toInteger() ?: 0

Using Groovy Script, How to access the dynamic soap request which is stored in MessageExchange in a Data-Driven Approach?

I am trying a data driven approach in soap ui using groovy script and I wanted to export each of the dynamic request and response from MessageExchange to an Excel sheet. I am using the input data Excel file "dataFile.xls" for a simple "Login" operation. It consists of 2 fields Username and Password with 4 records. My script is doing a data driven approach and executing all the records from the excel file. But I wanted to export all the four dynamic request and response into an Excel file "Output.xls". My soap pack is having 2 groovy test request(one for data driver and the other for looping), one property test step to hold the input element properties and temporary variables, one soap test request "login". Below is the code snippet I am using in the "data driver" groovy test step.
// IMPORT THE LIBRARIES WE NEED
import com.eviware.soapui.support.XmlHolder
import jxl.*
import jxl.write.*
import com.eviware.soapui.model.iface.MessageExchange
// DECLARE THE VARIABLES
def myTestCase = context.testCase //myTestCase contains the test case
log.info(myTestCase)
def counter,next,previous,size //Variables used to handle the loop and to move inside the file
Workbook workbook1 = Workbook.getWorkbook(new File("d:\\Groovy videos\\dataFile.xls")) //file containing the data
Sheet sheet1 = workbook1.getSheet(0) //save the first sheet in sheet1
size = sheet1.getRows().toInteger() //get the number of rows, each row is a data set
log.info(size)
propTestStep = myTestCase.getTestStepByName("Property - Looper") // get the Property TestStep object
log.info(propTestStep)
req = myTestCase.getTestStepByName("login").getProperty("Request").getValue()
//log.info(req)
propTestStep.setPropertyValue("Total", size.toString())
counter = propTestStep.getPropertyValue("Count").toString() //counter variable contains iteration number
counter = counter.toInteger() //
next = (counter > size-2? 0: counter+1) //set the next value
// OBTAINING THE DATA YOU NEED
Cell u = sheet1.getCell(0,counter) // getCell(column,row) //obtains user
Cell p = sheet1.getCell(1,counter) // obtains password
workbook1.close() //close the file
////////////////////////////////////
usr = u.getContents()
pass = p.getContents()
propTestStep.setPropertyValue("user", usr) //the value is saved in the property
propTestStep.setPropertyValue("pass", pass) //the value is saved in the property
propTestStep.setPropertyValue("Count", next.toString()) //increase Count value
next++ //increase next value
propTestStep.setPropertyValue("Next", next.toString()) //set Next value on the properties step
WritableWorkbook workbook2 = Workbook.createWorkbook(new File("d:\\output.xls"))
WritableSheet sheet2 = workbook2.createSheet("Request", 0)
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def temp=testRunner.testCase.testSteps["login"]
def testStepContext = new com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext(temp)
def reqq = testStepContext.getRequestContent()
log.info(reqq)
//def temp=testRunner.testCase.testSteps.testRequest.getRequestContent()
//holder = groovyUtils.getXmlHolder(messageExchange.requestContent)
log.info("request : "+temp)
Label label1 = new Label(0, 6, temp);
sheet2.addCell(label1);
workbook2.write()
workbook2.close()
//Decide if the test has to be run again or not
if (counter == size-1)
{
propTestStep.setPropertyValue("StopLoop", "T")
log.info "Setting the stoploop property now..."
}
else if (counter==0)
{
def runner = new com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner(testRunner.testCase, null)
propTestStep.setPropertyValue("StopLoop", "F")
}
else
{
propTestStep.setPropertyValue("StopLoop", "F")
}
I am getting the fault
"groovy.lang.MissingMethodException: No signature of method: com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext.getRequestContent() is applicable for argument types: () values: [] error at line: 50"
Could some one please help me in this.
The main objective is to get all the dynamic request and response from the MessageExchange and export all the data into the excel sheet.
Your program throws the exception there:
def testStepContext = new com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext(temp)
def reqq = testStepContext.getRequestContent()
log.info(reqq)
The exception is pretty clear MissingMethodException so the problem is that com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext doesn't have getRequestContent() method.
Anyway in your code you only use reqq on log.info(reqq)... then without analyzing the whole code the easy solution to solve the problem is simply remove this lines due they are useless.
You better make use of project level event "TestRunListener.afterStep" to accomplish your task.
In this event you'll have access to testRunner, context & testStepResult Objects. The following code snippet can help you.
For Soap Services:
if (context.getCurrentStep() instanceof WsdlTestRequestStep) {
WsdlTestStepResult soapResult= (WsdlTestStepResult) testStepResult;
log.info "Request: "+soapResult.getRequestContent();
log.info "Response: "+soapResult.getResponseContent();
}
For Rest Services:
if (context.getCurrentStep() instanceof RestTestRequestStep) {
RestRequestStepResult restResult= (RestRequestStepResult) testStepResult;
log.info "Request: "+restResult.getRequestContent();
log.info "Response: "+restResult.getResponseContent();
}

Optimize Groovy code

I am fairly new to the Groovy/Grails arena. I recently modified some code to add the following block.
result.processed.each{
def queueEntry = QueueEntry.findById(it.id)<<<START ADD>>>
Set dates = new HashSet<Long>()
def children = QueueEntry.findAllByParent(queueEntry)
for(QueueEntry qe : children){
def f = new GregorianCalendar()
f.setTimeInMillis(DateUtils.getClearedTime(qe.entryTimestamp))
def l = new GregorianCalendar()
l.setTimeInMillis(DateUtils.getClearedTime(qe.exitTimestamp))
while(f < l){
if(f.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY && f.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY){//only add weekdays
dates.add(f.time.time)
}
def xx = new GregorianCalendar()
xx.setTimeInMillis(f.time.next().time)
f = xx
}
dates.add(l.time.time)
} <<<STOP ADD>>>
Set outsideDays = it.numberOfDaysOutsideCVB
Set days = DateUtils.businessDaysBetweenDates(it.entryTimestamp, it.exitTimestamp)
days.removeAll(outsideDays)
days.removeAll(dates)
turnTimes << days.size()
}
The application is now crawling. I am obviously doing something wrong. When this is run for small data-sets it will complete slowly. On larger sets it doesn't finish. Prior to this change it was completing.
You can start with the lines of the below changes.
// Proposed
import static java.util.Calendar.*
// Query for all the children upfront instead of hitting
// database twice on each iteration.
// You can also avoid N + 1 situation if children is fetched eagerly
def allChildren = QueueEntry.where {
id in (result.processed*.id as List<Long>)
}.children.list()
def turnTimes = result.processed.collect { entry ->
allChildren.findAll { it.parent.id == entry.id }.collect { child ->
Set dates = []
new Date( child.entryTimeStamp ).upto( new Date( child.exitTimestamp ) ) {
if ( !( it[DAY_OF_WEEK] in [ SUNDAY, SATURDAY ] ) ) {
dates << it.time
}
}
Set outsideDays = child.numberOfDaysOutsideCVB
Set days =
DateUtils.businessDaysBetweenDates(
child.entryTimestamp,
child.exitTimestamp
)
( days - outsideDays - dates )?.size() ?: 0
}
}
Assumptions:
QueueEntry hasMany children
entryTimestamp/exitTimestamp is java.sql.Timestamp
entryTimestamp/exitTimestamp are not null and entryTimestamp comes before exitTimestamp.
As Burt suggested this question best fits in codereview.stackexchange.com

Need to Update XML Tag value at run time

In the code below I'm trying to update one of the tag value. My problem is that which tag value I need to update, I know only at run time.
Below code does not work to update the tag value even though I'm able to get the tag value by this code.
def temp1="""
<TradeRecord>
<TradeId>1000</TradeId>
<SecurityId>10382456</SecurityId>
<TradeType>SELLL</TradeType>
<TradeDate>2014-03-21</TradeDate>
<Broker>100</Broker>
<Exchange>1</Exchange>
<Status>INIT</Status>
<Quantity>12765</Quantity>
<ApprovedBy />
</TradeRecord>
"""
def records = new XmlParser().parseText(temp1)
childRecords = records.children()
j = childRecords.size()
def tagname = 'Quantity'
for (int i=0; i<j; i++){
if (childRecords[i].name() == tagname) {
log.info childRecords[i].text()
childRecords[i].text() = "9999"
log.info childRecords[i].text()
}
}
You can not assign to the text()-getter, but there is the value, which has a setter; e.g.:
childRecords[i].value = "9999"
But this also can be done more groovy:
def temp1="""
<TradeRecord>
<TradeId>1000</TradeId>
<SecurityId>10382456</SecurityId>
<TradeType>SELLL</TradeType>
<TradeDate>2014-03-21</TradeDate>
<Broker>100</Broker>
<Exchange>1</Exchange>
<Status>INIT</Status>
<Quantity>12765</Quantity>
<ApprovedBy />
</TradeRecord>
"""
def records = new XmlParser().parseText(temp1)
final tagname = 'Quantity'
records."$tagname".each{
it.value = '9999'
}
println groovy.xml.XmlUtil.serialize(records)

Resources