Groovy assertion on SOAP UI for database output - groovy

Using SOAP UI I am running query and fetching data for an specific ID and after that I want to validate specific field and its corresponding Value which is returning .
Ex -
Version =2
So I want to validate that every time for the generated record the version is 2 .
I checked and came up with the below code but the Select query is giving me error ,where it is unable to read value returning from recordId variable which i am using in Where condition ,So how to resolve it ?
The below is the database result which i want to validate
here
def listOfPostedRecordIds = parser.parseText(context.expand( '${1.CreateTestData#IdsToBeDeleted}' ))
def **recordId**=listOfPostedRecordIds[0]
log.info "recordId is "+recordId
def Version = myDB.firstRow('''Select cast(("Research"."meta"#>>'{versionId}') as integer)as Version from "Research"where id= **("recordId")** ''')
log.info "The value of is ${Version}

To parameterize data in your SQL in Groovy, do it with a ? like this:
def recordId = listOfPostedRecordIds[0]
def Version = myDB.firstRow("""
Select cast(('ResearchSubject'.'meta'#>>'{versionId}') as integer) as Version
from 'ResearchSubject'
where id = ?;""", [recordId])
log.info "The value of is ${Version}"
Also note that your select is quite complicated with ", ', # >> and {}. Make sure all those are really required.

Related

Python PYODBC INSERT - Too Few Parameters

I've been over this multiple times, I've taken a copy of the database file for testing purposes and even renamed the field to match the Python script. So the field name I am using in Python matches the tables field name exactly.
import pyodbc
def main():
tble="SomeTable"
fld1="SomeField"
val1="TestValue"
sqlStrng = """INSERT INTO %s (%s) VALUES(%s);""" %(tble, fld1,val1)
contStrng = (
r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=Some\Path\File.accdb;'
)
cnnctn = pyodbc.connect(contStrng)
cursr = cnnct.cursor()
cursr.execute(sqlStrng)
cnnctn.commit()
cnnctn.close()
This isn't a spelling issue. I've made a testing copy of the Access file and created a table called SomeTable with a field called SomeField. I have the correct path, I've verified this by running a SELECT SQL script, which works without issue.
I've tried making fld1 a parameter and then sending that with the execute command, but then I'm informed I need 0 parameters. When I remove it, I'm informed I need 1.
I'm beginning to think perhaps it's this file? The same code works on another file I have. However I created a brand new file, and same results. I have to be missing something.
If you print(sqlStrng) immediately after assigning it you'll see that its value is
INSERT INTO SomeTable (SomeField) VALUES(TestValue);
The Access Database Engine treats unrecognized names as parameters, so it wants to be given a parameter value for name TestValue. If you want to insert the string value 'TestValue' then you should use a pyodbc parameter placeholder (?) and pass val1 as a parameter in the .execute method, like so:
tble="SomeTable"
fld1="SomeField"
val1="TestValue"
sqlStrng = """INSERT INTO [%s] ([%s]) VALUES(?);""" %(tble, fld1)
contStrng = (
r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=Some\Path\File.accdb;'
)
cnnctn = pyodbc.connect(contStrng)
cursr = cnnct.cursor()
cursr.execute(sqlStrng, val1)
Notice that you wouldn't get an error if SomeField was a Number field and you used val1=123 because 123 would be treated as a numeric literal, not an unrecognized name (unquoted text value).

if condition not displaying correct message after output

I am having a little issue with my if condition in groovy.
Virtually I want to look at a property value I've set and ensure that is every instance on the response delivered from the JSON contains the same value as the property value, then it should equal a match. Now when I log the location_id and location_id_request, I am getting the values expected. However, in my if statement it seems to still state that that the location id does not match, making me believe that my if condition is incorrect. What do I need to change my if condition to, to output the correct message.
Below is the code I have with the log information underneath:
import groovy.json.JsonSlurper
def response = messageExchange.response.responseContent
def json = new JsonSlurper().parseText(response)
def location_id = json.reviews.location_id
assert location_id != null
def location_id_request = messageExchange.modelItem.testStep.testCase.getPropertyValue("locationid")
assert location_id.every {it == location_id_request}
log.info location_id_request
log.info location_id
if (location_id == location_id_request)
log.info "Good News, location match!"
else
log.info "Test has failed, location do not match!"
Log information in correct order:
location_id_request:INFO:000000
location_id:INFO:[000000, 000000, 000000, 000000, 000000]
if condition output:INFO:Test has failed, location do not match!
You compare a String (Number?) with List - it won't work. Instead, try to check if given location_id is present on location_id_request List:
if (location_id in location_id_request) { //... }

How to save id using groovy from response?

in soapui my project is :
Project
|__Datasource
|__request
|__groovy_code
|__DatasourceLoop
My Datasource contains 100 lines, each one is a request with different parameters.
My groovy_code save the id from the response of the request.
When i run my project, it executes 100 requests without errors.
groovy_code save only the first id.
What i want is to save id for each request, so 100 ids in different variables at project level
Here is my groovy_code:
import groovy.json.JsonSlurper
def response = context.expand( '${login#Response#declare namespace ns1=\'https://elsian/ns/20110518\'; //ns1:login_resp[1]/ns1:item[1]/ns1:response[1]}' )
def slurper = new JsonSlurper()
def result = slurper.parseText(response)
log.info result.data.id
testRunner.testCase.testSuite.project.setPropertyValue("token_id", result.data.id)
Thank you for your help
I never use SOAPUI PRO and I don't have access to datasource testStep or even datasource loop.
However based on the project structure you're showing I suppose that for each time datasource loop founds a element in datasource it sends the flow to request step so request and groovy steps are executed on each iteration; due to this I think that the problem is that your groovy code is overriding each time the same property with a new value.
Then to solve this you can try adding some variable suffix to your property name to avoid override each time the property value. For example you can add to token_id string a counter, some uuid, current ms etc.
For example you can use a counter as a suffix. To keep the counter value you've to save it in the context variable, this way this property are shared between your tests inside the current execution:
import groovy.json.JsonSlurper
// create a suffix function to generate
// the suffixs for your property names based on a count
def getSuffixNameProperty = {
// check if already exists
if(context['count']){
// if exists simply add 1
context['count']++
}else{
// if not exists initialize the counter
context['count'] = 1
}
return context['count']
}
def propertyName = "token_id" + getSuffixNameProperty();
def response = context.expand( '${login#Response#declare namespace ns1=\'https://elsian/ns/20110518\'; //ns1:login_resp[1]/ns1:item[1]/ns1:response[1]}' )
def slurper = new JsonSlurper()
def result = slurper.parseText(response)
testRunner.testCase.testSuite.project.setPropertyValue(propertyName, result.data.id)

using an assert with a contains in groovy

I am trying to run an assert with contains but am encountering an issue. I have written the code below using groovy in SOAPUI Pro
def pieceid = context.expand( '${OneDX#ResponseAsXml#//Results[1]/ResultSet[1]/Row[1]/PIECEID[1]}' )
def TrackingNumber = context.expand( '${OneDX#ResponseAsXml#//Results[1]/ResultSet[1]/Row[1]/TRACKINGNUMBER[1]}' )
assert {!TrackingNumber.contains(Pieceid)}
The tracking number is 907598985733 and Pieceid is 1820480....therefore the Pieceid is not in the tracking number. However when I run the script it passes. do you know what i'm doing wrong
Looks like a trivial issue in this case.
Changes:
replace ResponseAsXml with Response
removed { .. } in the assert statement, and introduced ( .. )
looks, you used incorrect variable i.e., Pieceid which is also not available - incorrect case.
Here is you go with the changed groovy script snippet:
def pieceid = context.expand( '${OneDX#Response#//Results[1]/ResultSet[1]/Row[1]/PIECEID[1]}' )
def trackingNumber = context.expand( '${OneDX#Response#//Results[1]/ResultSet[1]/Row[1]/TRACKINGNUMBER[1]}' )
log.info "Tracking number is $trackingNumber and Piece Id is $pieceid"
assert (!trackingNumber.contains(pieceid)), "Tracking number contains Pieceid"
You should be able to see the data of both variables in the log as well.
I would also like to recommend you not to use indexes in the xpath. Understand that might be auto generated by the tool. The reason being that if nodes come in different order, that will break your existing assertions for later test executions.

Setting json key using bind variables in groovy

I've this code by which I am trying to set the value of a Key (a json node id). But its not setting the value. Log.info statement is showing right values.
Key= context.expand( '${#Project#key}' )
Value= context.expand( '${#Project#value}' )
Binding binding = new Binding()
binding.setVariable("v", "$Value")
binding.setVariable("k", "$Key")
log.info(binding.getVariable("v")) // gives me the value 1234
log.info(binding.getVariable("k")) // gives me the value request.id
def SetKey = new GroovyShell(binding).evaluate( "k=v")
Can someone please comment on whats wrong in this code. and how can I correct it.
Edit: Explanation of the issue
In SoapUI I've some json nodes saved in data source like this request.id and request.app.id and there expected values in Value column which I am fetching through Key and Value above. I am hoping to change the value of a json node to its respective value at run time. So for each iteration of data source, it should set the correct value of that particular json node. Befor the above code I've parsed my json request by json slurper and after the above code I am building the json again by Json builder and running the request. Parsing and running the request works fine, its just that I couldnt set the value of the json node.
If your keys are just dotted names, you could simply use some string manipulation, no need to involve the Groovy parser.
For example, if they all begin with request:
def steps = Key.split(/\./)
if (steps.size() < 2 || steps[0] != 'request') {
throw ...
}
def obj = request
if (steps.size() > 2) {
steps[1..-2].each {
obj = obj[it]
}
}
obj[steps[-1]] = Value

Resources