SOAP UI Assertion Help : To validate Total attribute and Total Value - json

I searched in Google and Stackoverflow and I didn't find any helpful information and decide to post question.
I am getting response from API in JSON.
{
"CouponCode": [{
"id": 56,
"name": "BlackFriday"
}, {
"id": 58,
"name": "ThanksGiving"
}, {
"id": 62,
"name": "New Year"
}]}
I need to add assertion that will count that there are total 3 id and 3 name.
All IDs and Names are not empty. We don't want to send empty attribute value.
I am using SOAP UI open source. Please provide exact code or exact reference.
Exactly assertion needs to
Find total Ids and Name that's will be size
Find total Ids and Name size.
If Id is 3 and 3 Ids value are three..if JSON come like in this case assertion will failed.
this
{
"CouponCode": [{
"id": 56,
"name": "BlackFriday"
}, {
"id": 58,
"name": "ThanksGiving"
}, {
"id": "",
"name": "New Year"
}]}

The below groovy script uses json way to check the expected results.
Add the groovy script step after the rest request step in your test case.
Sudo code for extracting the same.
Read the json text. If you do not want to use fixed response, read it from previous step response. Create the object.
Make sure you have the expected counts for id, and name. You may also define them at test case custom properties in case do not want to use fixed values and change each time in the script.
find all the id count and check with expected value and show the error message in case of failure.
Similar to step 3, do the assert for names.
//for testing using fixed response, you may aslo assign dynamic response.
def jsonText = '''
{
"CouponCode": [{
"id": 56,
"name": "BlackFriday"
}, {
"id": 58,
"name": "ThanksGiving"
}, {
"id": 62,
"name": "New Year"
}]}'''
def coupons = new groovy.json.JsonSlurper().parseText(jsonText).CouponCode
//You may also read these values from test case properties
def expectedIdCount = 3
def expectedNameCount = 3
//assert the expected id count with find all coupon ids count of json response
assert expectedIdCount == coupons.findAll{it.id}.size(), "Coupon id count does not match"
//assert the expected name count with find all coupon names count of json response
assert expectedNameCount == coupons.findAll{it.name}.size(), "Coupon name count does not match"
The same can be achieved using script assertion for the rest step as well, that will avoid additional groovy script step. But it may require little changes in the script as below.
How to read the json response dynamically?
From script assertion
Use below line and remove the fixed jsonText from above.
def jsonText = messageExchange.response.responseContent
From Groovy script step
//replace the rest request step name below
def jsonText = context.expand('${ReplaceStepName#Response}')
How to read the test case level properties for expected results instead of hardcoded values in the script?
Define a test case level property for id, say EXPECTED_ID_COUNT and provide value 3 like you mentioned and similarly, define for name as well.
//read in script these properties
def expectedIdCount = context.testCase.getPropertyValue('EXPECTED_ID_COUNT') as Integer

There are several possible solutions. The easiest is to use an XPath assertion; keep in mind that internally, SoapUI converts everything to XML if it can.
count(//*:id)
expected result:
3
Similarly for your name.

Related

Length is not worked in JSON Extractor in Jmeter

I need to get the count of card from json file. For this I've used $.storedCards.cards.lenght
in JSON Extractor but it doesn't work. There is an error message:
Options AS_PATH_LIST and ALWAYS_RETURN_LIST are not allowed when using path functions!
After that I've tried JSR223 PostProcessor with next script on goovy
def jsonText = '''${AllCards}''' //${AllCards} has json value
def json = new JsonSlurper().parseText(jsonText)
log.info( "Json length---------->"+json.resource.size())
${CardsCount} = props.get("4") //vars.put(json.resource.size.toString())
but there is problem with set value to my variable. Or when i've created variable in Groovy it was impossible to use outside from script.
My json file
"storedCards":
{
"cards":
[
{
"CardId":"123",
"cardBrand":"Visa",
"lastFourDigits":"2968",
},
{
"CardId":"321",
"cardBrand":"Visa",
"lastFourDigits":"2968",
},
..........
],
How can i get the count of card and set to my Variables? what should i use for this?
Your JSON data seems to be invalid. Assuming you have the valid JSON like below, I'm answering your question.
{
"storedCards": {
"cards": [
{
"CardId": "123",
"cardBrand": "Visa",
"lastFourDigits": "2968"
},
{
"CardId": "321",
"cardBrand": "Visa",
"lastFourDigits": "2968"
}
]
}
}
You dont need to write Groovy code, you can resolve this using JSON Extractor. Instead of using length function, use JSON path predicate like this-
$.storedCards.cards[*]
Though Variable you used in JSON Extractor won't give the solution right away, another JMeter function helps - __RandomFromMultipleVars
Excerpt from documentation -
The RandomFromMultipleVars function returns a random value based on the variable values provided by Source Variables.
The variables can be simple or multi-valued as they can be generated by the following extractors:
Boundary Extractor
Regular Expression Extractor
CSS Selector Extractor
JSON Extractor
XPath Extractor
XPath2 Extractor
Multi-value vars are the ones that are extracted when you set -1 for
Match Numbers. This leads to creation of match number variable called
varName_matchNr and for each value to the creation of variable
varName_n where n = 1, 2, 3 etc.
So once you use the predicate, you will get the count in the yourVariableName_matchNr. Example:-
Hope this help.

How to validate entire JSON with 1 dynamic field with JMeter

I have a JSR223 Assertion in JMeter that validates entire JSON response and its working.
The problem is that each time I insert data in DB one of JSON fields changes and validation fails.
How could I skip that dynamic field from response validation?
Response JSON example:
[
{
"id": "273444",
"trxDateTime": "2019-03-25T22:38:16Z",
"merchantName": "MerchECOM1",
"merchantTransId": "1r1vXue4qn",
"trxType": "Payment",
"paymentBrand": "MasterCard",
"amount": 20.00,
"currencyCode": "AUD",
"status": "Declined",
"statusResponseMessage": null,
"customerAccount": "123456"
}
]
JSR223 Assertion:
def expected = new groovy.json.JsonSlurper().parseText(vars.get('expected1'))
def actual = new groovy.json.JsonSlurper().parse(prev.getResponseData())
if (expected != actual) {
AssertionResult.setFailure(true)
AssertionResult.setFailureMessage('Mismatch between expected and actual JSON')
}
just with this I'm not able to validate the dynamic "id" field
any idea?
Thanks in advance
If you're not interested in this id field - just remove it from the expected variable and the actual response, to wit amend first 2 lines of your assertion to look like:
def expected = new groovy.json.JsonSlurper().parseText(vars.get('expected1')).each {entry -> entry.remove('id')}
def actual = new groovy.json.JsonSlurper().parse(prev.getResponseData()).each {entry -> entry.remove('id')}
More information:
Groovy: Parsing and Producing JSON
Apache Groovy - Why and How You Should Use It
Demo:
If value is not your concern for id field you can directly use regex matcher to check the field using Jsonassertion by specifying jsonpath and check match as regex use regex

How to parse JSON and access a value

From this,
{
“students”: [
{
“name”: “test1”,
"id": 1,
"created_at": "2019-03-13T21:34:30Z",
"updated_at": "2019-03-13T21:34:30Z",
“title”: "My test ticket2",
"description": “My test description!”
}
],
"count": 1
}
How can I get the value of id, description and count? I did:
JSON.parse(response)
but I am not sure how to get the value.
You need to parse twice, if you just parse once you will get the error:
TypeError: no implicit conversion of Hash into String
you should do like that:
parsed_response = JSON.parse(response.to_json)
Then you can get the values as you need:
parsed_response['students'][0]['id']
You can also use the dig method if your ruby version is higher than 2.3:
parsed_response.dig('students', 0, 'id')
=> 1
JSON.parse returns hash.
Fetching information about student:
parsed_response = JSON.parse(response)
parsed_response['students'].first['id']
parsed_response['students'].first['name']
parsed_response['students'].first['description']
If you have more than one values, iterate over them with each.
Fetching count:
parsed_response = JSON.parse(response)
parsed_response['count']
Instead of [] you can use fetch (parsed_response.fetch('students')). Please keep in mind, that fetch raises an error when the key is missing.

Creating assertions using Groovy where JSON contains multiple objects with the same name

I'm currently writing some tests in ReadyAPI to test a new API that we are building. The API will return JSON in the following format:
{
"testJSON" : [
{
"test1" : "111",
"test2" : "ABC"
},
{
"test1" : "222",
"test2" : "DEF"
}
]
}
I have added the following Groovy code that breaks down the JSON and lists each value:
import groovy.json.JsonSlurper
def jsonResp = context.expand( '${GetTest#Response}' )
def jsonElements = new JsonSlurper().parseText(jsonResp)
for ( value in jsonElements.testInput ) {
value.each{
log.info "${it.key}:${it.value}"
}
}
What I am trying to do is to take this JSON response and compare it to a pre-defined list of data (using a Data Source within ReadyAPI). This data source will contain a column titled 'test1' and a column titled 'test2' -these will contain all the values expected for each object. So we would need to ensure that each test1 value from the datasource is displayed in the response JSON. And we'd also like to confirm that for each 'test1' we get the correct corresponding 'test2'.
So in example above, we'd want to prove that the response contained 'test1' values of 111 and 222, and that for 111 we got a 'test2' value of ABC etc.
The example above is a simplistic view of our new API and in reality it will contain a much larger number of fields and a lot more responses. So ideally, I don't want to have to hard code specific values within the Groovy script - which is why I'm trying to use a data sheet.
Has anyone had any experience of this sort of thing and can make any suggestions?
Thanks in advance for your help, please let me know if you need any more information.
Cheers,
Matt
"testJSON" is a list of objects containing properties "list1" and "list2".
Your datasource is also a list of objects (rows) containing properties (columns) "list1" and "list2".
Use a nested for loop to compare each expected object with each object in the response. Use a boolean flag to track whether test1 is missing from the response. When test1 is found, check the value of test2.
Here's the basic outline. I'm assuming test1 is a unique identifier for each object. You may also want to exit the inner loop when you do find test1, to be more efficient.
for (element in datasource) {
def foundTest1 = false
for (response in testJSON) {
if (response.test1 == element.test1){
foundTest1 = true
assert response.test2 == element.test2
// assert any number of other properties here
}
}
assert foundTest1 == true
}

Reusing type definitions with JSONProvider?

I'm using the JSONProvider from FSharp-Data to automatically create types for a webservice that I'm consuming using sample responses from the service.
However I'm a bit confused when it comes to types that are reused in the service, like for example there is one api method that return a single item of type X while another returns a list of X and so on. Do I really have to generate multiple definitions for this, and won't that mean that I will have duplicate types for the same thing?
So, I guess what I'm really asking, is there a way to create composite types from types generated from JSON samples?
If you call JsonProvider separately with separate samples, then you will get duplicate types for the same things in the sample. Sadly, there is not much that the F# Data library can do about this.
One option that you have would be to pass multiple samples to the JsonProvider at the same time (using the SampleIsList parameters). In that case, it tries to find one type for all the samples you provide - but it will also share types with the same structure among all the samples.
I assume you do not want to get one type for all your samples - in that case, you can wrap the individual samples with additional JSON object like this (here, the real samples are the records nested under "one" and "two"):
type J = JsonProvider<"""
[ { "one": { "person": {"name": "Tomas"} } },
{ "two": { "num": 42, "other": {"name": "Tomas"} } } ]""", SampleIsList=true>
Now, you can run the Parse method and wrap the samples in a new JSON object using "one" or "two", depending on which sample you are processing:
let j1 = """{ "person": {"name": "Tomas"} }"""
let o1 = J.Parse("""{"one":""" + j1 + "}").One.Value
let j2 = """{ "num": 42, "other": {"name": "Tomas"} }"""
let o2 = J.Parse("""{"two":""" + j2 + "}").Two.Value
The "one" and "two" records are completely arbitrary (I just added them to have two separate names). We wrap the JSON before parsing it and then we access it using the One or Two property. However, it means that o1.Person and o2.Other are now of the same type:
o1.Person = o2.Other
This returns false because we do not implement equality on JSON values in F# Data, but it type checks - so the types are the same.
This is fairly complicated, so I would probably look for other ways of doing what you need - but it is one way to get shared types among multiple JSON samples.