Checking a value across multiple arrays - groovy

I have a context property named 'flights'. I want to check if there is no value for this property, then go to the 'Iteration' test step, else set the first value of the property as a test case property.
Now what I want to do is perform a compare using this test case property value with a couple of arrays. Below is the scenario;
Check if value is in the villas array, if so +1 to VillasCount, else check in hotels array, if in there then +1 to beachCount else +1 to noCount.
Code is below:
// define properties required for the script to run.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def dataFolder = groovyUtils.projectPath
//Define an empty array list to load data from datasheet
def dataTable_properties = [];
int villasCount = context.getProperty("villasCount")
def lines = new File(dataFolder + "/Test.csv").readLines()
def villas = []
lines.eachWithIndex { line, index ->
if (index) {
def data = line.split(',')*.trim()
if (data[0]) villas << data[0]
}
}
log.info "Villas : ${villas}"
context.setProperty("villasCount", villasCount)

Maybe something like:
for(f in flights){
if(villas.contains(f)){
villasCount = villasCount + 1
}
}
Not 100% sure what you needed to compare, but you could easily expand this to check whatever you wanted.
If this is way off please provide more information on what you were trying to compare.

Related

How to use map in groovy

Here is how my script currently looks like -
baseList = readFile('text2.txt').split('\n') as List
def cleanList = []
for (i=0; i < baseList.size; i++) {
if (baseList[i].contains('=')){
cleanList += baseList[i]
}
}
print(cleanList)
This gives following output-
[Pipeline] echo
[version.build=874, version.maintenance=0, version.major=1, version.minor=37]
I want these values to go into another variable called "svnTag"
def svnTag="ccsmp_v_${version.major} ${version.minor} ${version.maintenance} ${version.build}"
So that when I print svnTag, it output something like this-
SVN_TAG=ccsmp_v_1.37.0.846
You are not using a Map, but a List of String, where each element is in the form of <key>=<value>
If you want to parse your file to a Map, you could use something like:
def baseList = readFile('text2.txt').split('\n') as List
def map = [:]
for (el in baseList) {
if (el.contains('=')) {
def parts = el.split('=')
map[parts[0]] = parts[1]
}
}
Then you can use the values from the map with:
def svnTag="ccsmp_v_${map['version.major']} ${map['version.minor']} ${map['version.maintenance']} ${map['version.build']}"
If your file is a valid property file (all lines are in form of key=value), you can use the readProperties step that will create a Properties object for you (that is in fact a Map):
def map = readProperties file: 'text2.txt'

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()

soapUI: How to set lists as property

I want to do the following in soapUI using Groovy:
Select random value and correspondating data from database
Get the response from webservice
Compare my database data with the response from the webservice
To achieve this I have the following steps definied:
Created property object for the test suite
Groovy Script to get the random and correspondating values from database
Transformation to put the random value into the request
Webservice call to get response
Groovy Script to compare the values from my database with the response of the webservice
I did the same steps for other tests already by putting the values from database into the property object in step 2 and reading them from there in step 5. But up to now the values were always normal String or int. In the response I get in my current test case I get a list back. So I create an array and filled it with bean objects my wanted data in step 2. In step 5 I parse my XML-String and convert the data into an Object-Array too. So I can compare all attributes of them.
I wrote the whole test case in a singular script and tested it on groovy console first. When I started to transform it to soapUI and working with the property to "transport" the data from step 2 to step 5 my problem occurs as it looks like I can't put an Arraylist to the properties (see error message below).
Now I'm confused that this is not possible as I can easily put SQL-Instances in the properties:
def contextSqlInstanz = Sql.newInstance(urlH2, userH2, passwordH2, driverH2)
context.setProperty( "contextSqlInstanz", contextSqlInstanz )
sql = context.getProperty("contextSqlInstanz");
So how I can transport my Array, filled the Objects, from step 2 to step 5 to compare it with my webservice response. I DON'T want to convert both to strings and compare if the strings are equal but I want to compare each attributes of my bean-class by hand.
Bean Class:
class myBean {
String value1;
String value2;
...
}
Reading my local database, generating the beans and put them into a list
function getdata() {
def liste = []
// sql-statements
sql.eachRow(...) {
def myBean = new myBean();
myBean.value1 = it.value1.toString();
myBean.value2 = it.value2.toString();
...
liste.add(Schluesselwert)
}
return liste
}
Trying to put the list into properties
sollListeH2 = getdata()
def props = testRunner.testCase.getTestStepByName("P_testcase")
props.setPropertyValue( "sollListe", sollListeH2)
results in:
groovy.lang.MissingMethodException: No signature of method: com.eviware.soapui.impl.wsdl.teststeps.WsdlPropertiesTestStep.setPropertyValue() is applicable for argument types: (java.lang.String, java.util.ArrayList) values: [sollListe, [value1#15d4334, value2#1e739c8, ...]] Possible solutions: setPropertyValue(java.lang.String, java.lang.String), getPropertyValue(java.lang.String) error at line: 91
As I didn't find another way I did it the ugly way by putting each value as an own property into the propteries
Setting the props in step 2:
def convertVectorToProps(vector) {
def size = vector.size();
def props = testRunner.testCase.getTestStepByName("P_testcase")
props.setPropertyValue("sollSize", size.toString())
for(int i=0; i < size; i++) {
props.setPropertyValue("myBean.value1" + i, vector.value1[i]);
props.setPropertyValue("myBean.value2" + i, vector.value2[i]);
...
}
}
Reading the props in step 5 and build new vector:
def convertPropsToVector() {
def props = testRunner.testCase.getTestStepByName("P_testcase")
def sollSize = props.getPropertyValue("sollSize").toInteger()
SollListe = [];
for(int i=0; i < sollSize; i++) {
def myBean = new myBean();
myBean.value1 = props.getPropertyValue("myBean.value1" + i);
myBean.value2 = props.getPropertyValue("myBean.value2" + i);
SollListe << myBean
}
return SollListe
}

Finding a value of a list

I have two lists
def flagList = SystemFlag.list()
this contains the domain objects of one table
I have another list which I create using a query. One of the parameter in the object of this list is contained in the flagList. How can I find if an id of FlagList is present in the second list?
I can do it in plain java but I need to use Groovy for this.
If I understood you correctly you have this situation:
def listeOne = [1,2,3,4,5]
def listTwo = [2,5,1]
You want to see if '2' of 'listTwo' is in 'listOne'.
Find a specific value:
def found = 2 in listTwo //returns a boolean of the interger 2 is in listTwo
Search for common value of both lists:
def intersectionsList = listOne.intersect(listTwo) //gives you a list of value that are in BORTH list
You can also iterate like this:
listTwo.each { value ->
if(value in listOne) println value //or do something lese
}
Alternatively:
listTwo.each { value ->
listOne.find {value}?.toString() //you can perform an action on the object found in listOne. using '?.' will make sure no nullpointer will be thrown if there is no result.
}
I found it using
def it = itemtofindsomehow
list.findIndexof { iterator ->
iterator.domain.id == it.id
}

Sorting arrays in Groovy

I'm trying to compare two arrays in groovy. My attempts so far have yielded a mixed response and therefore I'm turning to the collective for advice.
In the following code I'm taking 2 REST responses, parsing them and placing everything under the Invoice node into an array. I then further qualify my array so I have a list of InvoiceIDs and then try to compare the results of the two responses to ensure they are the same.
When I compare the array of InvoiceIDs (Guids) they match - this is not what I expect as the invoice order is currently different between my my 2 response sources.
When I sort the arrays of Invoices IDs the results differ.
I'm suspecting my code is faulty, but have spent an hour rattling through it, to no avail.
Any advice on sorting arrays in groovy or on the code below would be most appreciated:
gu = new com.eviware.soapui.support.GroovyUtils( context )
def xmlSlurper = new groovy.util.XmlSlurper()
// Setting up the response parameters
def responseSTAGE = xmlSlurper.parseText(context.expand('${GET Invoices - STAGE#Response}'));
def responseSTAGE2 = xmlSlurper.parseText(context.expand('${GET Invoices - STAGE2#Response}'));
responseInvoicesSTAGE = responseSTAGE.Invoices
responseInvoicesSTAGE2 = responseSTAGE2.Invoices
def arrayOfInvoicesSTAGE = []
def arrayOfInvoicesSTAGE2 = []
def counter = 0
for (invoice in responseInvoicesSTAGE.Invoice) {
arrayOfInvoicesSTAGE[counter] = responseInvoicesSTAGE.Invoice[counter].InvoiceID
//log.info counter+" STAGE"+arrayOfInvoicesSTAGE[counter]
arrayOfInvoicesSTAGE2[counter] = responseInvoicesSTAGE2.Invoice[counter].InvoiceID
//log.info counter+" STAGE2"+arrayOfInvoicesSTAGE2[counter]
counter++
}
log.info arrayOfInvoicesSTAGE
log.info arrayOfInvoicesSTAGE2
def sortedSTAGE = arrayOfInvoicesSTAGE.sort()
def sortedSTAGE2 = arrayOfInvoicesSTAGE2.sort()
log.info sortedSTAGE
As an aside, can't you replace:
def arrayOfInvoicesSTAGE = []
def arrayOfInvoicesSTAGE2 = []
def counter = 0
for (invoice in responseInvoicesSTAGE.Invoice) {
arrayOfInvoicesSTAGE[counter] = responseInvoicesSTAGE.Invoice[counter].InvoiceID
//log.info counter+" STAGE"+arrayOfInvoicesSTAGE[counter]
arrayOfInvoicesSTAGE2[counter] = responseInvoicesSTAGE2.Invoice[counter].InvoiceID
//log.info counter+" STAGE2"+arrayOfInvoicesSTAGE2[counter]
counter++
}
with
def arrayOfInvoicesSTAGE = responseInvoicesSTAGE.Invoice*.InvoiceID
def arrayOfInvoicesSTAGE2 = responseInvoicesSTAGE2.Invoice*.InvoiceID
Two arrays are considered equal in Groovy if they have they have the same number of elements and each element in the same position are equal. You can verify this by running the following code in the Groovy console
Integer[] foo = [1,2,3,4]
Integer[] bar = [4,3,2,1]
assert foo != bar
bar.sort()
assert foo == bar

Resources