sopaui test - extract response value and use it in a flat text - json

I've a JSON response like this:
{
"id":"1",
"key":"123145"
}
I need to use the value of "key" as input for a payload request:
param=1&param=2&param3=$key
I would like to write the request like :
param=1&param=2&param3=${keyValue}
so the result should be
param=1&param=2&param3=12345
I've tried with Property Transfer but doesn't works.
Any suggestion?

You could use a property transfer test step like this:
Here you're transferring a value to a test-case level property called myProperty (which you created previously). Then, you can reference this property in your URL as ${#TestCase#myProperty}

So you can proceed like below
1) Fetch value you want from json using groovy step
2) Store the fetched value from Groovy Step into TestCase Property
3) Use that value in the request you want
import groovy.json.JsonSlurper
def input=context.expand('${SampleRequest#Request}')
log.info input
def jsonObj=new JsonSlurper().parseText(input)
def key=jsonObj.key
log.info key
testRunner.testCase.setPropertyValue("Key",key)
The value stored can be used as below in a request. Syntax to access Property Value
${#TestCase#Key}

Related

How to validate JSON's specific element against DB data in JMeter

I want to perform validation of JSON response against DB data.
For example I have a student table with column as "StudentID" , "StudentName" and "StudentAddress"
and In JSON response we have element as "StudentNumber", "StuName" and "StuAddress" (Name is different in both JSON and DB)
Question 1: How can I compare entire JSON against the DB data to match it in JMeter.
Question 2: If I want to perform validation like if in Database "StudentID"=1 then in JSON response "StudentNumber" should be equal to "A". How can I validate it in JMeter in a single script
If you want to compare entire JSON to the result of the database query which returns more than 1 row - the only option is going for JSON Assertion and implementing your pass/fail criteria in Groovy.
Groovy has built-in JSON support so it can parse the response as JSON and convert it to maps/lists/values
Groovy can iterate the ResultSet object containing the query results, see Debugging JDBC Sampler Results in JMeter for more details
If you want to compare individual entries:
In the JDBC Test Element specify variable name to store the value from the database
Use JSON Extractor or JSON JMESPath Extractor to store the value from JSON
Compare 2 variables using Response Assertion
Following is a sample code used within a JSR223 element to process JSON response
import groovy.json.JsonSlurper
try{
def responseJSON = prev.getResponseDataAsString()
if(responseJSON) {
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(responseJSON)
def itemCount = object['items']['id'].size()
log.info("Items $itemCount")
for (i in 0..<itemCount){
log.info("Student Number ${object['items']['id'][i]}")
log.info("Student Name ${object['items']['studentName'][i]}")
log.info("Address ${object['items']['address'][i]}")
}
}catch (anything){
log.info("Error ")
}
Groovy has support for working with JSON. Documentation.

How to Transfer a JSON value from a REST POST Response to a REST PUT Request in SOAPUI

I have a REST service which I am testing with SoapUI. The first step in my TestSuite returns the Response (Json): 'policyID' then I need to put this in another request ( i.e, test step) to get the final response - which is newly created policy number. I have written a code in groovy
import groovy.json.*
def response = context.expand('${CreateApplication#Response}')
def json = new JsonSlurper().parseText(response) --- Error line
log.info json.policyId
context.testCase2.setPropertyValue("id",json.policyID.toString())
I am getting error
Java.lang.ilegal.arguementexception :the JSON INPUT TEXT should should
neither be null nor empty
This error is coming at the line above marked as error, could you guys please help as I am not able to figure it out
If I understood the question correctly:
You can do below steps:
create a property transfer step.
Select source as ur first REST step response
Select Property Raw Response
Select Path Language as JsonPath
Use Jsonpath $.id.
In Target section use your testcase name
Create a test case level property "id"
Go to Property transfer step and select the same property name "id" in property section
save the project.
In the next step (REST) use id like below :
{ "id": "${#TestCase#id}", "issued": "1999-01-01", "policyId": "1011, "name":"test321"}
Hope this is clear?

GCP Proto Datastore encode JsonProperty in base64

I store a blob of Json in the datastore using JsonProperty.
I don't know the structure of the json data.
I am using endpoints proto datastore in order to retrieve my data.
The probleme is the json property is encoded in base64 and I want a plain json object.
For the example, the json data will be:
{
first: 1,
second: 2
}
My code looks something like:
import endpoints
from google.appengine.ext import ndb
from protorpc import remote
from endpoints_proto_datastore.ndb import EndpointsModel
class Model(EndpointsModel):
data = ndb.JsonProperty()
#endpoints.api(name='myapi', version='v1', description='My Sample API')
class DataEndpoint(remote.Service):
#Model.method(path='mymodel2', http_method='POST',
name='mymodel.insert')
def MyModelInsert(self, my_model):
my_model.data = {"first": 1, "second": 2}
my_model.put()
return my_model
#Model.method(path='mymodel/{entityKey}',
http_method='GET',
name='mymodel.get')
def getMyModel(self, model):
print(model.data)
return model
API = endpoints.api_server([DataEndpoint])
When I call the api for getting a model, I get:
POST /_ah/api/myapi/v1/mymodel2
{
"data": "eyJzZWNvbmQiOiAyLCAiZmlyc3QiOiAxfQ=="
}
where eyJzZWNvbmQiOiAyLCAiZmlyc3QiOiAxfQ== is the base64 encoded of {"second": 2, "first": 1}
And the print statement give me: {u'second': 2, u'first': 1}
So, in the method, I can explore the json blob data as a python dict.
But, in the api call, the data is encoded in base64.
I expeted the api call to give me:
{
'data': {
'second': 2,
'first': 1
}
}
How can I get this result?
After the discussion in the comments of your question, let me share with you a sample code that you can use in order to store a JSON object in Datastore (it will be stored as a string), and later retrieve it in such a way that:
It will show as plain JSON after the API call.
You will be able to parse it again to a Python dict using eval.
I hope I understood correctly your issue, and this helps you with it.
import endpoints
from google.appengine.ext import ndb
from protorpc import remote
from endpoints_proto_datastore.ndb import EndpointsModel
class Sample(EndpointsModel):
column1 = ndb.StringProperty()
column2 = ndb.IntegerProperty()
column3 = ndb.StringProperty()
#endpoints.api(name='myapi', version='v1', description='My Sample API')
class MyApi(remote.Service):
# URL: .../_ah/api/myapi/v1/mymodel - POSTS A NEW ENTITY
#Sample.method(path='mymodel', http_method='GET', name='Sample.insert')
def MyModelInsert(self, my_model):
dict={'first':1, 'second':2}
dict_str=str(dict)
my_model.column1="Year"
my_model.column2=2018
my_model.column3=dict_str
my_model.put()
return my_model
# URL: .../_ah/api/myapi/v1/mymodel/{ID} - RETRIEVES AN ENTITY BY ITS ID
#Sample.method(request_fields=('id',), path='mymodel/{id}', http_method='GET', name='Sample.get')
def MyModelGet(self, my_model):
if not my_model.from_datastore:
raise endpoints.NotFoundException('MyModel not found.')
dict=eval(my_model.column3)
print("This is the Python dict recovered from a string: {}".format(dict))
return my_model
application = endpoints.api_server([MyApi], restricted=False)
I have tested this code using the development server, but it should work the same in production using App Engine with Endpoints and Datastore.
After querying the first endpoint, it will create a new Entity which you will be able to find in Datastore, and which contains a property column3 with your JSON data in string format:
Then, if you use the ID of that entity to retrieve it, in your browser it will show the string without any strange encoding, just plain JSON:
And in the console, you will be able to see that this string can be converted to a Python dict (or also a JSON, using the json module if you prefer):
I hope I have not missed any point of what you want to achieve, but I think all the most important points are covered with this code: a property being a JSON object, store it in Datastore, retrieve it in a readable format, and being able to use it again as JSON/dict.
Update:
I think you should have a look at the list of available Property Types yourself, in order to find which one fits your requirements better. However, as an additional note, I have done a quick test working with a StructuredProperty (a property inside another property), by adding these modifications to the code:
#Define the nested model (your JSON object)
class Structured(EndpointsModel):
first = ndb.IntegerProperty()
second = ndb.IntegerProperty()
#Here I added a new property for simplicity; remember, StackOverflow does not write code for you :)
class Sample(EndpointsModel):
column1 = ndb.StringProperty()
column2 = ndb.IntegerProperty()
column3 = ndb.StringProperty()
column4 = ndb.StructuredProperty(Structured)
#Modify this endpoint definition to add a new property
#Sample.method(request_fields=('id',), path='mymodel/{id}', http_method='GET', name='Sample.get')
def MyModelGet(self, my_model):
if not my_model.from_datastore:
raise endpoints.NotFoundException('MyModel not found.')
#Add the new nested property here
dict=eval(my_model.column3)
my_model.column4=dict
print(json.dumps(my_model.column3))
print("This is the Python dict recovered from a string: {}".format(dict))
return my_model
With these changes, the response of the call to the endpoint looks like:
Now column4 is a JSON object itself (although it is not printed in-line, I do not think that should be a problem.
I hope this helps too. If this is not the exact behavior you want, maybe should play around with the Property Types available, but I do not think there is one type to which you can print a Python dict (or JSON object) without previously converting it to a String.

How to match json response in 2 requests?

I have a json response in 1 request like this:
{"total":1,"page":1,"records":2,"rows":[{"id":1034,"item_type_val":"Business
Requirement","field_name":"Assigned To","invalid_value":"Jmeter
System","dep_value":"","dep_field":""},{"id":1033,"item_type_val":"Risk","field_name":"Category","invalid_value":"Energy","dep_value":"Logged
User","dep_field":"Assigned To"}]}
and in 2nd request like this:
{"total":1,"page":1,"records":2,"rows":[{"id":1100,"item_type_val":"Business
Requirement","field_name":"Assigned To","invalid_value":"Jmeter
System","dep_value":"","dep_field":""},{"id":1111,"item_type_val":"Risk","field_name":"Category","invalid_value":"Energy","dep_value":"Logged
User","dep_field":"Assigned To"}]}
Both are same but different id's. I need to verify the 1st json response from 2nd json response and compare both that both are same or not. here both are same but having different id's which should be acceptable. how can i do this by regex so i can ignore the id's and match whole content?
Not sure if you can do it with a single regex but other way out is you can create a map of it and then compare everything except 'id'
I believe the easiest way would be just discarding these id entries using JSR223 PostProcessor and Groovy language which comes with JSON support
Add JSR223 PostProcessor as a child of the sampler, which returns your JSON
Put the following code into the JSR223 PostProcessor's "Script" area
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
def slurper = new JsonSlurper()
def jsonResponse = slurper.parseText(prev.getResponseDataAsString())
jsonResponse.rows.findAll { it.remove("id") }
def newResponse = new JsonBuilder(jsonResponse).toPrettyString()
//depending on what you need
vars.put("responseWithoutId", newResponse) // store response withou ID into a JMeter Variable
prev.setResponseData(new String(newResponse)) // overwrite parent sampler response data
log.info(newResponse) // just print the new value to jmeter.log file
So you have the following choices:
vars.put("responseWithoutId", newResponse) - stores the new JSON (without these id) into a ${responseWithoutId} JMeter Variable
prev.setResponseData(new String(newResponse)) - after this line execution parent sampler data won't contain any "id"
log.info(newResponse) - just prints JSON without "id" to jmeter.log file
I don't know your test plan design, personally I would store responses from 2 requests into 2 different JMeter Variables i.e. ${response1} and ${response2} using above approach and compare them with the Response Assertion like:

xpath and soapui, Transfer Property. Getting nested JSON from a Get to a Post in a Test Suite

I am trying to learn SoapUI and I have not found any good guides on how to perform a transfer property from a Rest GET request to a Rest POST request.
I have the following payload returned from a REST GET request
{
"a":"a",
"b": { "b1":"b1", "b2":"b2" },
"c":"c"
}
I want to take this JSON and remove c, then submit the rest to a POST request. I wish to post
{
"a":"a",
"b": { "b1":"b1", "b2":"b2" },
}
I am trying to do all this in SoapUI, but have had no success. I am able to get individual values by saying in the source property is RseponseAsXML and the target property is Request. Then I use the command //*:a. But it only returns that value.
I do not want this to be xml though, I am working strictly with JSON.
Thank you.
If you want to manipulate the JSON response to use in other TestStep it's easier to use groovy TestStep instead of Transfer testStep. So create a groovy TestStep and manipulate the response using the following code:
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
// get the response using the name of your test step
def response = context.expand('${REST Test Request#Response}')
// parse response
def jsonResp = new JsonSlurper().parseText(response)
// remove "c" element
jsonResp.remove("c")
// parse json to string in order to save it as a property
def jsonAsString = JsonOutput.toJson(jsonResp)
log.info jsonAsString // prints --> {"b":{"b1":"b1","b2":"b2"},"a":"a"}
// save the json response without "c" in a testCase property
testRunner.testCase.setPropertyValue('json_post',jsonAsString)
With the code above you parse the response, remove the c element and save as a property in the testCase then in your REST POST you can use the follow code to get your new JSON:
${#TestCase#json_post}
Hope this helps,