重载JSONComparator比对JSON Response,忽略小数点后几位,将科学计数法转换为普通数字进行比对
封装的脚本:
package direct import org.skyscreamer.jsonassert.* import org.skyscreamer.jsonassert.comparator.* import org.json.* import net.sf.json.JSONException import java.text.NumberFormat public class LooseyJSONComparator extends DefaultComparator { def log def regEx_Numeric = '-?[1-9]\\d*$|-?([1-9]\\d*\\.\\d*|0\\.\\d*|0?\\.0+|0)$' def regEx_ScientificNotation = '^((-?\\d+.?\\d*)[Ee]{1}(-?\\d+))$' //科学计数法正则表达式 int decimalPrecision = 5 //Defaultly compare 5 decimal places public LooseyJSONComparator(JSONCompareMode mode) { super(mode) } public static void assertEquals( Object expected, Object actual) throws JSONException { JSONCompareResult result = JSONCompare.compareJSON(expected, actual, new LooseyJSONComparator(JSONCompareMode.LENIENT)) if (result.failed()) { throw new AssertionError(result.getMessage()) } } @Override public void compareValues(String prefix, Object expectedValue, Object actualValue, JSONCompareResult result) throws JSONException { if (expectedValue instanceof String && actualValue instanceof String) { def expectedValueTemp=formatDecimalPrecision(expectedValue) def actualValueTemp=formatDecimalPrecision(actualValue) if (expectedValueTemp!=actualValueTemp){ result.fail(prefix, expectedValue, actualValue) } } else if (expectedValue.getClass().isAssignableFrom(actualValue.getClass())) { if (expectedValue instanceof JSONArray) { compareJSONArray(prefix, (JSONArray) expectedValue, (JSONArray) actualValue, result) } else if (expectedValue instanceof JSONObject) { compareJSON(prefix, (JSONObject) expectedValue, (JSONObject) actualValue, result) } else if (!expectedValue.equals(actualValue)) { result.fail(prefix, expectedValue, actualValue) } } else { result.fail(prefix, expectedValue, actualValue) } } def formatDecimalPrecision(def dataValue){ NumberFormat format = NumberFormat.getNumberInstance() format.setMaximumFractionDigits(decimalPrecision) dataValue = dataValue.toString() if(dataValue.matches(regEx_ScientificNotation)){ BigDecimal db = new BigDecimal(dataValue) dataValue = db.toPlainString() } if(dataValue.matches(regEx_Numeric)){ dataValue = Double.parseDouble(dataValue) dataValue = format.format(dataValue) } return dataValue } }
SoapUI里面如此调用
package direct import org.json.* def currentStepIndex = context.currentStepIndex def previousStepName = testRunner.testCase.getTestStepAt(currentStepIndex-1).name def prePreStepName = testRunner.testCase.getTestStepAt(currentStepIndex-2).name def expectedJsonResponse =new JSONObject("{\"long-rescale\":\"1.519719\",\"short\":\"0.105816\",\"net\":\"1.477390\",\"long\":\"1.583196\"}") def actualJsonResponse = new JSONObject("{\"long-rescale\":\"1.519715\",\"short\":\"0.105806\",\"net\":\"1.477390\",\"long\":\"1.583196\"}") LooseyJSONComparator.assertEquals( expectedJsonResponse, actualJsonResponse)
输出结果:
如果是通过获取test step的response来比对,脚本如下:
package direct import org.json.* def currentStepIndex = context.currentStepIndex def previousStepName = testRunner.testCase.getTestStepAt(currentStepIndex-1).name def prePreStepName = testRunner.testCase.getTestStepAt(currentStepIndex-2).name try{ def expectedJsonResponse = new JSONObject(context.expand( '${'+prePreStepName+'#Response}' )) def actualJsonResponse = new JSONObject(context.expand( '${'+previousStepName+'#Response}' )) LooseyJSONComparator.assertEquals( expectedJsonResponse, actualJsonResponse) }catch(JSONException e){ assert false,"HTTP Response returns wrong, please have a check" }