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.)
Related
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}"
}
I got a string from a server response:
responseString:"{"session":"vvSbMInXHRJuZQ==","age":7200,"prid":"901Vjmx9qenYKw","userid":"user_1"}"
then I do:
responseString[1..-2].tokenize(',')
got:
[""session":"vvSbMInXHRJuZQ=="", ""age":7200", ""prid":"901Vjmx9qenYKw"", ""userid":"user_1""]
get(3) got:
""userid":"user_1""
what I need is the user_1, is there anyway I can actually get it? I have been stuck here, other json methods get similar result, how to remove the outside ""?
Thanks.
If you pull out the proper JSON from responseStr, then you can use JsonSlurper, as shown below:
def s = 'responseString:"{"session":"vvSbMInXHRJuZQ==","age":7200,"prid":"901Vjmx9qenYKw","userid":"user_1"}"'
def matcher = (s =~ /responseString:"(.*)"/)
assert matcher.matches()
def responseStr = matcher[0][1]
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def json = jsonSlurper.parseText(responseStr)
assert "user_1" == json.userid
This code can help you get you to the userid.
def str= 'responseString:"{:"session":"vvSbMInXHRJuZQ==","age":7200,"prid":"901Vjmx9qenYKw","userid":"user_1","hdkshfsd":"sdfsdfsdf"}'
def match = (str=~ /"userid":"(.*?)"/)
log.info match[0][1]
this pattern can help you getting any of the values you want from the string. Try replacing userid with age, you will get that
def match = (str=~ /"age":"(.*?)"/)
#Michael code is also correct. Its just that you have clarified that you want the user Name to be specific
I am writing a Groovy script assertion which is verifying a value from a previous JDBC response step against a value contained in a SOAP response.
When I run my scripts I can see that both values are coming back the same but the actual result value (from the SOAP response) is surrounded by square brackets which in turn makes the assert fail. I'm guessing this is something to do with one being a string and one not?
How do I either strip out the square brackets from actual result or get them added to the expected result value to ensure the assert passes?
Below is my assert script.
Expected result is 001
Actual result is [001]
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def holder = groovyUtils.getXmlHolder( messageExchange.responseContent )
def pxml = new XmlSlurper().parseText(context.response)
//grab the expected result from jdbc response
def expectedCodes = context.expand( '${JDBC Request#ResponseAsXml#//*:TW304_PRODHIST.PRODUCT_1}' )
//grab the actual result from the SOAP response
def actualCodes = pxml.'**'.findAll{it.name() == 'CurrHospProductCode'}*.text()
assert expectedCodes == actualCodes
log.info expectedCodes
log.info actualCodes
Because you are expecting a single value as expected where as you are getting an array with single element in it.
You can do it as below if that is right :
assert expectedCodes == actualCodes[0]
On a side note, you may have to check carefully are you really expecting single value only or if there is possible to get list of values.
EDIT: based on your script.
findAll gives you list as result. If you are expecting single element in the xml, then you can change it to find and then you actual code should work as it is.
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()
I am trying to retrieve a list of all instances of 'search' from a json response and set it so that any values that contains 'null' is changed to 0. However I am getting an error stating no such property: it for class. How can I fix this to ensure I get the code working so any instance of 'null' changes to 0?
import groovy.json.JsonSlurper
def response = messageExchange.response.responseContent
def json = new JsonSlurper().parseText(response)
def resultItems = json.xxx.xxx.items
def resultSearchCostGroup = json.xxx.xxx.xxx.search
int totalSearchCostGroup = resultSearchCostGroup.flatten().collect(it ?:0 ).sum()
Your last line should read
int totalSearchCostGroup = resultSearchCostGroup.flatten().collect { it ?:0 }.sum()