SoapUI to read request parameters from a file ( free version) - groovy

I have a file with following contents
987656
987534
I have a Groovy script as following as a test step before my test :
def myTestCase = context.testCase
new File("filepath/data1.txt").eachLine { line ->
myTestCase.setPropertyValue("inputValue", line)
inputValue = context.expand( '${#TestCase#inputValue}' )
log.info inputValue
}
The log output for the script gives me both the values from the file :
987656
987534
I have a Testcase custom property set up as "inputValue" and in my test I call the parameter as
<enr:Id>${#TestCase#inputValue}</enr:Id>
During execution the test always runs for the last value "987534" and not for both the inputs.
What should I be doing to execute the test for all the values present in the text file?
Thanks

The way to loop through values like that is to, in the eachLine loop, call the SOAP step, like this:
def myTestCase = context.testCase
new File("filepath/data1.txt").eachLine { line ->
myTestCase.setPropertyValue("inputValue", line)
inputValue = context.expand( "${#TestCase#inputValue}" )
log.info inputValue
//define the step
def soapTestStep = testRunner.testCase.getTestStepByName("YourSOAPRequestName").name
//call the step
testRunner.runTestStepByName(soapTestStep)
//if you want to do something with the response XML
def responseSOAP = context.expand("${YourSOAPRequestName#Response}")
//if you want to check a value in the response XML
def responseSection = responseSOAP =~ /someNode>(.*)<\/someNode/
def responseValue = responseSection[0][1]
log.info "response: ${responseValue}"
}

Related

Passing value from Groovy script to DataSync in SoapUI

I have a script that loops through a dataset X and for each record in that dataset X loops in another dataset Y and retrieves some results. How can I pass those results to a DataSink?
A number of suggestions around have been to use properties however in my groovy script I have a loop within which i receive the results and if i populate a property with every result i guess i will only be able to see the last result in the property, and my DataSink will only find the last result.
My code below:
def goodWeather = context.expand( '${#TestCase#goodWeather}' ) as String
if (goodWeather.equals("false"))
{
def response = context.expand( '${CityWeatherRequest#Response#declare namespace ns1=\'http://tempuri.org/\'; //ns1:GetCityWeatherResponse[1]/ns1:GetCityWeatherResult[1]/ns1:Weather[1]}' )
def cityinfo_City = context.expand( '${GetCitiesDS#cityinfo_City}' )
def cityinfo_Country = context.expand( '${GetCitiesDS#cityinfo_Country}' )
//Keep count to restrict number of returns. CountSuggestedCities is a property.
def count = context.expand( '${#TestCase#countSuggestedCities}' ) as Integer
assert count instanceof Integer
//Suggest some cities if skies are clear
if (response.contains("clear sky"))
{
if (count == 0) log.info("Making suggestions")
count ++
testRunner.testCase.setPropertyValue("countSuggestedCities", count.toString());
log.info(cityinfo_City + " located in: " + cityinfo_Country);
}
//Check property maxSuggestedCities to see if maximum suggestes required as been reached.
if (count == (context.expand( '${#TestCase#maxSuggestedCities}' ) as Integer))
{
testRunner.testCase.setPropertyValue("countSuggestedCities", "0");
testRunner.testCase.setPropertyValue("goodWeather", "true");
testRunner.gotoStepByName("SeperatorScript");
}
}
else
{
testRunner.gotoStepByName("SeperatorScript");
}
What I want is to replace log.info(cityinfo_City + " located in: " + cityinfo_Country); with saving that information to a database using a DataSink.
I don't think the soapui doc provides examples about DataSink with groovy and database. But you can always use Groovy sql to do the insertion. Here is the example code:
def driverName = "com.mysql.jdbc.Driver"
com.eviware.soapui.support.GroovyUtils.registerJdbcDriver(driverName)
def user = "root" // change this , password, and jdbc url
def password = ""
def con = groovy.sql.Sql.newInstance("jdbc:mysql://localhost:3306/test_for_so",
user, password, driverName)
def cityinfo_City = 'London'
def cityinfo_Country = 'England'
con.execute("INSERT INTO cityinfo (cityinfo_City, cityinfo_Country) VALUES (?, ?)",
[cityinfo_City, cityinfo_Country])
con.close()

can file be named with today's date in groovy

I am doing soapui testing, wherein i want to save request & response suffixed with todaydate.
here's my code:
// Create a File object representing the folder 'A/B'
def folder = new File( 'C:/Project/SOAPUI' )
// If it doesn't exist
if( !folder.exists() ) {
// Create all folders up-to and including B
folder.mkdirs()
}
def myOutFile = "C:/Project/SOAPUI/test_request.txt"
def request = context.expand( '${test#Request}' )
def f = new File(myOutFile)
f.write(request, "UTF-8")
=====================
I want the file name to be test_request(+today's date)
Can you suggest me some options?
Here's an option:
def myOutFile = "C:/Project/SOAPUI/test_request_${(new Date()).format('yyyy-MM-dd')}.txt"
The output looks like C:/Project/SOAPUI/test_request_2015-08-30.txt

How to add child elements dynamically to SOAP request in SOAPUI using groovy script

I have a request which accepts 1..n items to add to basket. default request has one "item" element with some child elements, i want to add N no of items with child element i'm able to add Item parent element using creaeElementNS now i want to add child elements to "item" like following, can someone shed some light on this
<basket:item>
<basket:itemId>222</basket:itemId>
<basket:itemCode>DEF</basket:itemCode>
<basket:item>
Groovy script
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def holder = groovyUtils.getXmlHolder( "createBasket#Request" )
def parentnode = holder.getDomNode( "//basket:createBasketRequest" )
def basketTotal= holder.getDomNode( "//basket:itemsTotal" )
def itemsTag = requestDoc.createElementNS(parentnode.getNamespaceURI(), "item")
parentnode.insertBefore(itemsTag , basketTotal)
holder.updateProperty()
Current Output
<basket:createBasketRequest>
<basket:item>
<basket:itemId>111</basket:itemId>
<basket:itemCode>ABC</basket:itemCode>
</basket:item>
<basket:item>
</basket:item>
<basket:itemsTotal>500.00</basket:itemsTotal>
</basket:createBasketRequest>
Desired Output
<basket:createBasketRequest>
<basket:item>
<basket:itemId>111</basket:itemId>
<basket:itemCode>ABC</basket:itemCode>
</basket:item>
<basket:item>
<basket:itemId>222</basket:itemId>
<basket:itemCode>DEF</basket:itemCode>
<basket:item>
<basket:itemsTotal>500.00</basket:itemsTotal>
</basket:createBasketRequest>
EDIT: I'm using soapUI and TestCase option, there is a GroovyScript step before add basket request step, groovy script prepares add basket request before actually sending request, for example if my testcase mentions 1 item it should request with default one item so i have no worries to add another Item elements but when my testcase says 2 items i have to create second Items elements(along with child elements) and prepare the add basket request using groovy script step before actually sending add basket request
Not sure if it will work (I don't use SoapUI), but does this help?
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def holder = groovyUtils.getXmlHolder( "createBasket#Request" )
def parentnode = holder.getDomNode( "//basket:createBasketRequest" )
def basketTotal = holder.getDomNode( "//basket:itemsTotal" )
def nodeText = '''<basket:item>
| <basket:itemId>222</basket:itemId>
| <basket:itemCode>DEF</basket:itemCode>
|</basket:item>'''.stripMargin()
def nodeHolder = new com.eviware.soapui.support.XmlHolder( nodeText )
def nodeItem = nodeHolder.getDomNode( "//basket:item" )
def importNode = requestDoc.importNode( nodeItem, true )
parentnode.insertBefore( importNode, basketTotal )
holder.updateProperty()
Check out Scott Davis's post on creating XML with groovy
I used MarkupBuilder to create an XML that looks exactly like what you want.
def sw = new StringWriter()
def xml = new groovy.xml.MarkupBuilder(sw)
xml."basket:createBasketRequest"(){
"basket:item"(){
"basket.itemId"("111")
"basket:itemCode"("ABC")
}
"basket:item"(){
"basket.itemId"("222")
"basket:itemCode"("DEF")
}
"basket:itemsTotal"("500.00")
}
log.info sw
Output i got:
<basket:createBasketRequest>
<basket:item>
<basket.itemId>111</basket.itemId>
<basket:itemCode>ABC</basket:itemCode>
</basket:item>
<basket:item>
<basket.itemId>222</basket.itemId>
<basket:itemCode>DEF</basket:itemCode>
</basket:item>
<basket:itemsTotal>500.00</basket:itemsTotal>
</basket:createBasketRequest>
Updating response as some part of the XML already exists and nodes just have to be appended to the root.
Try this code...
import org.custommonkey.xmlunit.Diff
import org.custommonkey.xmlunit.XMLUnit
import groovy.xml.StreamingMarkupBuilder
def root = new XmlSlurper().parseText(orgXML)
root.appendNode {
"basket:item"{
"basket:itemID"("222")
"basket:itemCode"("DEF")
}
}
log.info groovy.xml.XmlUtil.serialize( root )

Why can't I see the programmatically inserted jenkins string parameters in the next groovy build step?

I am adding jenkins parameters to a job from system groovy script (one build step):
1-st step.
import hudson.model.*
def pa = new ParametersAction([
new StringParameterValue("firstParam", 1), new StringParameterValue("secondParam", 2)
])
Thread.currentThread().executable.addAction(pa)
Now when I try to execute the next system groovy build step, I am looking for them and they are not there:
2nd step.
def firstParam = "firstParam"
def secondParam = "secondParam"
def resolver = build.buildVariableResolver
def firstParamValue = resolver.resolve(firstParam)
def secondParamValue = resolver.resolve(secondParam)
println firstParamValue
println secondParamValue
they both print null! How do I get the parameters in the next system groovy build step?
The weird thing is that when I try a shell execution as a following step and if I do:
echo $firstParam
echo $secondParam
I get both 1 and 2 printed.
Even when I try to print all parameters with the below code I don't get them:
def thr = Thread.currentThread()
def build = thr?.executable
def parameters = build?.actions.find{ it instanceof ParametersAction }?.parameters
parameters.each {
println "parameter ${it.name}:"
println it.dump()
println "-" * 80
}
Your first build step didn't work for me, it gave a runtime error as the string parameters being set are integers not strings. I changed it to this and it works, the second step gets the parameters (I added quotes around integer values & used the 'build' variable for current build):
import hudson.model.*
def pa = new ParametersAction([
new StringParameterValue("firstParam", '1'), new StringParameterValue("secondParam", '2')
])
build.addAction(pa)
I am trying this on Jenkins v1.519.

using variables in groovy context.expand expression

I tried to automate a test case using groovy script and soapUI.
Sending a soap request, I got a response contains a company list.
What I'ld like to do is verifying names of listed companies.
Size of the response array is not fixed.
So I tried the script below just for the beginning but I got stuck..
def count = context.expand( '${Properties#count}' )
count = count.toInteger()
def i = 0
while (i<count)
(
def response = context.expand( '${getCompanyList#Response#//multiRef['+i+']/#id}' )
log.info(response)
i=İ+1
)
I get
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: Script12.groovy: 6: unexpected token: def # line 6, column 1. def response = context.expand( '${getCompanyList#Response#//multiRef['+i+']/#id}' ) ^ org.codehaus.groovy.syntax.SyntaxException: unexpected token: def # line 6, column 1. at
I should somehow put "i" in the "response" definition..
You are using the wrong characters to in your while statement, it should be braces ({}), not parentheses (()).
This is why the error is regarding the def on line 6, and has nothing to do with the i variable.
You also have İ in your example, which is not a valid variable name in Groovy.
I think you wanted this:
def count = context.expand( '${Properties#count}' )
count = count.toInteger()
def i = 0
while (i<count) {
def response = context.expand( '${getCompanyList#Response#//multiRef['+i+']/#id}' )
log.info(response)
i=i+1
}
However, this being Groovy, you can do this much cleaner using:
def count = context.expand( '${Properties#count}' )
count.toInteger().times { i ->
def response = context.expand( '${getCompanyList#Response#//multiRef['+i+']/#id}' )
log.info(response)
}
(And if you replace i inside the closure with it, you can remove the i -> as well.)

Resources