Ask a Question

Sorting data in JSON response for comparison

SOLVED
Shehnaz
Occasional Contributor

Sorting data in JSON response for comparison

I am trying to compare 2 full JSON responses - expected and actual for Pass/Fail status. After running the REST request, I get Actual response that does not return the field in same sequence as in Expected Response which causes 1 on 1 comparison to fail. To solve this issue, I need to sort the data in Actual Response to match it to Expected Response format before comparison. Below is the Expected and Actual response for reference. Can anyone help with this?

 

Expected Response -

{
"Drivers": [
{
"ContactId": 797952,
"LicenseNumber": "123WT45TY1234",
"LicenseState": "DE",
"DriverNumber": 2,
"DriverStatus": "Active",
"DriverTerminationDate": null,
"DriverUsed": true,
"PolicyDateTimeDriverAdd": "2021-01-06T14:27:34",
"PolicyDateTimeMax": "2021-01-06T14:27:34"
},
{
"ContactId": 797949,
"LicenseNumber": "N677DG8906VB7",
"LicenseState": "DE",
"DriverNumber": 1,
"DriverStatus": "Active",
"DriverTerminationDate": null,
"DriverUsed": true,
"PolicyDateTimeDriverAdd": "2021-01-06T14:27:34",
"PolicyDateTimeMax": "2021-01-06T14:27:34"
}
]

 

Actual Response - 

{
"Drivers": [
{
"ContactId": 797949,
"LicenseNumber": "N677DG8906VB7",
"LicenseState": "DE",
"DriverNumber": 1,
"DriverStatus": "Active",
"DriverTerminationDate": null,
"DriverUsed": true,
"PolicyDateTimeDriverAdd": "2021-01-06T14:27:34",
"PolicyDateTimeMax": "2021-01-06T14:27:34"
},
{
"ContactId": 797952,
"LicenseNumber": "123WT45TY1234",
"LicenseState": "DE",
"DriverNumber": 2,
"DriverStatus": "Active",
"DriverTerminationDate": null,
"DriverUsed": true,
"PolicyDateTimeDriverAdd": "2021-01-06T14:27:34",
"PolicyDateTimeMax": "2021-01-06T14:27:34"
}
]

 

I have highlighted field DriverNumber that I would like to sort the data before comparison in descending order 2,1,0.

 

5 REPLIES 5
nmrao
Champion Level 3

Take the respective driver from expected and match with the respective actual.
However, based on the above response, please clarify the following
- Is DriverNumber always unique? Looks it does not seem to be.


Regards,
Rao.
Shehnaz
Occasional Contributor

Hi Rao,

Yes, Driver Number is unique. But, I want to sort the Expected Response json Response based on Driver Number 1,2,3 before comparison so that my existing script for 1 on 1 comparison passes.

 

Can you please send the code to use to sort the response?

 

 

nmrao
Champion Level 3

Here is some similar example to retrieve data based on some property value. Please see if it can help!
https://github.com/nmrao/soapUIGroovyScripts/blob/master/groovy/json/QueryDataFromJsonSample.groovy

Then capture the object so that it can be compare with the correct object.


Regards,
Rao.

Hello @Shehnaz 

Below are two code examples of groovy scripts that can compare JSON... 

 

One:  It just sorts whatever the comparison strings are (regardless of JSON or not). Since your example is basically the same except for being out of order, you could use this example with your JSON.  It will sort each content (actual and expected) and compare them and show the difference or equality in the log output.

 

Two: Use the JSONAssert library (Obtain "jsonassert-1.5.0.jar" from http://jsonassert.skyscreamer.org/). You will need to put the .jar file in you installation .lib folder and then restart SoapUI/ReadyAPI.  Provide the library method with your actual and expected and it will respond with differences or equality.  The LENIENT parameter is used in this case since the order is different, but textual differences will be identified.  If you use STRICT, it will not allow a different order.

 

In either of these examples change a value and see what kind of response is returned when the comparison strings contain a different element value.

Maybe one of these examples will meet your need.

 

Regards,

Todd

 

Example One:  Groovy Script Sort And Compare Strings

log.info 'Test Step "' + testRunner.runContext.currentStep.name + '" start...';
log.info "";

def refStr = """
{
  "Drivers": [
    {
      "ContactId": 797952,
      "LicenseNumber": "123WT45TY1234",
      "LicenseState": "DE",
      "DriverNumber": 2,
      "DriverStatus": "Active",
      "DriverTerminationDate": null,
      "DriverUsed": true,
      "PolicyDateTimeDriverAdd": "2021-01-06T14:27:34",
      "PolicyDateTimeMax": "2021-01-06T14:27:34"
    },
    {
      "ContactId": 797949,
      "LicenseNumber": "N677DG8906VB7",
      "LicenseState": "DE",
      "DriverNumber": 1,
      "DriverStatus": "Active",
      "DriverTerminationDate": null,
      "DriverUsed": true,
      "PolicyDateTimeDriverAdd": "2021-01-06T14:27:34",
      "PolicyDateTimeMax": "2021-01-06T14:27:34"
    }
  ]
}
""";
refStr = refStr.replaceAll('}', '');   // without this, there is a close brace whose result is only differentiated by its existance
def refStrList = refStr.split();
def refStrListSorted = refStrList.sort();

log.info "refStrList.size()=" + refStrList.size();
refStrList.each { element ->
   log.info "element=" + element;
};
log.info "";
log.info "";
refStrListSorted.each { element ->
   log.info "element=" + element;
};


log.info "";
log.info "==================================================";
log.info "";

def compStr = """
{
  "Drivers": [
    {
      "ContactId": 797949,
      "LicenseNumber": "N677DG8906VB7",
      "LicenseState": "DE",
      "DriverNumber": 1,
      "DriverStatus": "Active",
      "DriverTerminationDate": null,
      "DriverUsed": true,
      "PolicyDateTimeDriverAdd": "2021-01-06T14:27:34",
      "PolicyDateTimeMax": "2021-01-06T14:27:34"
    },
    {
      "ContactId": 797952,
      "LicenseNumber": "123WT45TY1234",
      "LicenseState": "DE",
      "DriverNumber": 2,
      "DriverStatus": "Active",
      "DriverTerminationDate": null,
      "DriverUsed": true,
      "PolicyDateTimeDriverAdd": "2021-01-06T14:27:34",
      "PolicyDateTimeMax": "2021-01-06T14:27:34"
    }
  ]
}
""";
compStr = compStr.replaceAll('}', '');  // without this, there is a close brace whose result is only differentiated by its existance
def compStrList = compStr.split();
def compStrListSorted = compStrList.sort();

log.info "compStrList.size()=" + compStrList.size();
compStrList.each { element ->
   log.info "element=" + element;
};
log.info "";
log.info "";
compStrListSorted.each { element ->
   log.info "element=" + element;
};


log.info "";
log.info "==================================================";
log.info "";

// sanity check...
log.info "refStrList.size()=" + refStrList.size();
log.info "compStrList.size()=" + compStrList.size();
assert refStrList.size().equals(compStrList.size()), "Mismatch - There are ${refStrList.size()} reference values and ${compStrList.size()} compare values";

// sorted line by sorted line check...
refStrListSorted.eachWithIndex { refValue, idx ->
   def compValue = compStrListSorted[idx];
   if ( refValue != compValue ) {
      log.info "refValue=" + refValue + "  " + idx;
      log.info "compValue=" + compValue + "  " + idx;
      assert refValue.equals(compValue), "Mismatch - At index $idx the referece value '$refValue' does not match the comparison value '$compValue'";
   };
};

// If we get here, then the contents are equal
log.info "";
log.info "   ***  Reference and Compare strings are equal  ***";

log.info "";
log.info 'Test Step "' + testRunner.runContext.currentStep.name + '" done...';

 

Example Two: Groovy Script JSON Assert Lenient

import org.skyscreamer.jsonassert.*;      // Obtain jsonassert-1.5.0.jar from http://jsonassert.skyscreamer.org/

log.info 'Test Step "' + testRunner.runContext.currentStep.name + '" start...';
log.info "";

def String refStr = """
{
  "Drivers": [
    {
      "ContactId": 797952,
      "LicenseNumber": "123WT45TY1234",
      "LicenseState": "DE",
      "DriverNumber": 2,
      "DriverStatus": "Active",
      "DriverTerminationDate": null,
      "DriverUsed": true,
      "PolicyDateTimeDriverAdd": "2021-01-06T14:27:34",
      "PolicyDateTimeMax": "2021-01-06T14:27:34"
    },
    {
      "ContactId": 797949,
      "LicenseNumber": "N677DG8906VB7",
      "LicenseState": "DE",
      "DriverNumber": 1,
      "DriverStatus": "Active",
      "DriverTerminationDate": null,
      "DriverUsed": true,
      "PolicyDateTimeDriverAdd": "2021-01-06T14:27:34",
      "PolicyDateTimeMax": "2021-01-06T14:27:34"
    }
  ]
}
""";

//  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

def String compStr = """
{
  "Drivers": [
    {
      "ContactId": 797949,
      "LicenseNumber": "N677DG8906VB7",
      "LicenseState": "DE",
      "DriverNumber": 1,
      "DriverStatus": "Active",
      "DriverTerminationDate": null,
      "DriverUsed": true,
      "PolicyDateTimeDriverAdd": "2021-01-06T14:27:34",
      "PolicyDateTimeMax": "2021-01-06T14:27:34"
    },
    {
      "ContactId": 797952,
      "LicenseNumber": "123WT45TY1234",
      "LicenseState": "DE",
      "DriverNumber": 2,
      "DriverStatus": "Active",
      "DriverTerminationDate": null,
      "DriverUsed": true,
      "PolicyDateTimeDriverAdd": "2021-01-06T14:27:34",
      "PolicyDateTimeMax": "2021-01-06T14:27:34"
    }
  ]
}
""";

log.info "";
log.info "==================================================";
log.info "";

def actual = refStr;
def expected = compStr;

//JSONAssert.assertEquals(actual, expected, JSONCompareMode.STRICT);
JSONAssert.assertEquals(actual, expected, JSONCompareMode.LENIENT);

log.info "";
log.info 'Test Step "' + testRunner.runContext.currentStep.name + '" done...';

 

 

Shehnaz
Occasional Contributor

Hello @TN 

 

I tried with Example 1 and it's working as expected. Thank you for the solution.

 

In the code, after the step 

// sorted line by sorted line check...

 I am getting Assertion fail message - java.lang.AssertionError: Mismatch - At index 0 the referece value '"{\n' does not match the comparison value '"{\"Drivers\":[{\"ContactId\":501017,\"LicenseNumber\":\"'. Expression: refValue.equals(compValue) error at line: 66

 

Instead of Assertion, I would like to log results for Pass/Fail based on comparison and add logic of adding the Mismatch field and Key value to Temp Msg which I can use to log the results in DataSink excel spreadsheet. I tried below code but it's giving error - 

// sorted line by sorted line check...
refStrListSorted.eachWithIndex { refValue, idx ->
def tempmssg = "";
def compValue = compStrListSorted[idx];
if ( refValue != compValue ) {
tempmssg = "refValue=" + refValue + " " + idx +tempmssg;
}
else{
tempmssg = "compValue=" + compValue + " " + idx +tempmssg;
};
};

cancel
Showing results for 
Search instead for 
Did you mean: