package direct;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.JSONCompareResult;
import org.skyscreamer.jsonassert.comparator.DefaultComparator;
import org.skyscreamer.jsonassert.JSONCompare; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map; import static org.skyscreamer.jsonassert.comparator.JSONCompareUtil.*; /**
* Created by jenny zhang on 2017/9/19.
*/
public class LooseyJSONComparator extends DefaultComparator {
private int scale; //精度,scale=5,表示精确到小数点后5位
private Double accuracy; //精度,accuracy=0.00001,表示精确到小数点后5位
String extraInfo;
def log; public LooseyJSONComparator(JSONCompareMode mode, int scale,String extraInfo,def log) {
super(mode);
this.scale = scale;
this.accuracy = 1.0/Math.pow(10,scale);
this.extraInfo = extraInfo;
this.log = log;
} public static void assertEquals( String expected, String actual, int scale, String extraInfo, def log) throws JSONException {
JSONCompareResult result = JSONCompare.compareJSON(expected, actual, new LooseyJSONComparator(JSONCompareMode.NON_EXTENSIBLE,scale,extraInfo,log));
if (result.failed()) {
def failMessage = result.getMessage();
throw new AssertionError(extraInfo + failMessage);
}
else{
log.info "pass";
}
} @Override
protected void compareJSONArrayOfJsonObjects(String key, JSONArray expected, JSONArray actual, JSONCompareResult result) throws JSONException {
String uniqueKey = findUniqueKey(expected);
if (uniqueKey == null || !isUsableAsUniqueKey(uniqueKey, actual)) {
// An expensive last resort
recursivelyCompareJSONArray(key, expected, actual, result);
return;
} Map<Object, JSONObject> expectedValueMap = arrayOfJsonObjectToMap(expected, uniqueKey, log);
Map<Object, JSONObject> actualValueMap = arrayOfJsonObjectToMap(actual, uniqueKey, log); for (Object id : expectedValueMap.keySet()) {
if (!actualValueMap.containsKey(id)) {
result.missing(formatUniqueKey(key, uniqueKey, expectedValueMap.get(id).get(uniqueKey)),
expectedValueMap.get(id));
continue;
}
JSONObject expectedValue = expectedValueMap.get(id);
JSONObject actualValue = actualValueMap.get(id);
compareValues(formatUniqueKey(key, uniqueKey, id), expectedValue, actualValue, result);
}
for (Object id : actualValueMap.keySet()) {
if (!expectedValueMap.containsKey(id)) {
result.unexpected(formatUniqueKey(key, uniqueKey, actualValueMap.get(id).get(uniqueKey)), actualValueMap.get(id));
}
}
} private String getCompareValue(String value) {
try{
return new BigDecimal(value).setScale(scale, RoundingMode.HALF_EVEN).toString();
} catch (NumberFormatException e) {
return value; //value may = NaN, in this case, return value directly.
}
} private boolean isNumeric(Object value) {
try {
Double.parseDouble(value.toString());
return true;
} catch (NumberFormatException e) {
return false;
}
} public Map<Object, JSONObject> arrayOfJsonObjectToMap(JSONArray array, String uniqueKey,def log) throws JSONException {
Map<Object, JSONObject> valueMap = new HashMap<Object, JSONObject>();
for (int i = 0; i < array.length(); ++i) {
JSONObject jsonObject = (JSONObject) array.get(i);
Object id = jsonObject.get(uniqueKey);
id = isNumeric(id) ? getCompareValue(id.toString()) : id;
valueMap.put(id, jsonObject);
}
return valueMap;
} @Override
public void compareValues(String prefix, Object expectedValue, Object actualValue, JSONCompareResult result) throws JSONException {
if (areLeaf(expectedValue, actualValue)) { if (isNumeric(expectedValue) && isNumeric(actualValue)) {
//For special numeric, such as NaN, convert to string to compare
boolean equalsAsSpecialNumeric = (expectedValue.toString().equals(actualValue.toString())) //For normal numeric, such as 153.6960001, 1.56E5, subtract and then get abosolute value
boolean equalsAsGeneralNumeric = Math.abs(Double.parseDouble(expectedValue.toString())-Double.parseDouble(actualValue.toString()))<accuracy; if (equalsAsSpecialNumeric||equalsAsGeneralNumeric) {
result.passed();
} else {
result.fail(prefix, expectedValue, actualValue);
}
return;
}
}
super.compareValues(prefix, expectedValue, actualValue, result);
} private boolean areLeaf(Object expectedValue, Object actualValue) {
boolean isLeafExpectedValue = !(expectedValue instanceof JSONArray)&&!(expectedValue instanceof JSONObject);
boolean isLeafActualValue = !(actualValue instanceof JSONArray)&&!(actualValue instanceof JSONObject);
return isLeafExpectedValue&&isLeafActualValue;
}
}

  SoapUI 里面进行调用:

package direct
import org.json.* //Get test step name
def currentStepIndex = context.currentStepIndex
def previousStep = testRunner.testCase.getTestStepAt(currentStepIndex-1)
def prePreStep = testRunner.testCase.getTestStepAt(currentStepIndex-2) def previousStepName = previousStep.name
def prePreStepName = prePreStep.name //Get extra information, get case number in loop
String caseNum = context.expand('${DataSource#caseNumber}')
String extraInfo = caseNum+ ", " //Get more extra information, get request ID
try{
def requestIdTest =previousStep.testRequest.messageExchange.requestHeaders.get("X-API-RequestId")
def requestIdBmk =prePreStep.testRequest.messageExchange.requestHeaders.get("X-API-RequestId")
extraInfo += "requestIdBmk = "+requestIdBmk+", requestIdTest = "+requestIdTest+", "
}
catch(NullPointerException e){
assert false,extraInfo+"HTTP Request is null"
} //Get json response and compare them
try{
String expectedJsonResponse = new JSONObject(context.expand( '${'+prePreStepName+'#Response}' ))
String actualJsonResponse = new JSONObject(context.expand( '${'+previousStepName+'#Response}' ))
LooseyJSONComparator.assertEquals(expectedJsonResponse, actualJsonResponse,5,extraInfo,log)
}
catch(JSONException e){
assert false,extraInfo+"HTTP Response is not JSON"
}

  

【SoapUI】比较Json response的更多相关文章

  1. 使用Groovy处理SoapUI中Json response

    最近工作中,处理最多的就是xml和json类型response,在SoapUI中request里面直接添加assertion处理json response的话,可以采用以下方式: import gro ...

  2. [SoapUI] Compare JSON Response(比较jsonobject)

    http://jsonassert.skyscreamer.org/ 从这个网站下载jsonassert-1.5.0.jar ,也可以下载到源代码 JSONObject data = getRESTD ...

  3. [SoapUI] 比较JSON Response

    比较两个JSON, ID是数字时,处理成统一的格式:只保留小数点后5位 package direct; import org.json.JSONArray; import org.json.JSONE ...

  4. [SoapUI] 重载JSONComparator比对JSON Response,忽略小数点后几位,将科学计数法转换为普通数字进行比对,在错误信息中打印当前循环的case number及其他附加信息

    重载JSONComparator比对JSON Response,忽略小数点后几位,将科学计数法转换为普通数字进行比对,在错误信息中打印当前循环的case number及其他附加信息 package d ...

  5. datatable fix error–Invalid JSON response

    This error is pretty common. Meaning:When loading data by Ajax(ajax|option).DataTables by default, e ...

  6. [SoapUI] 通过JSONAssert比较两个环境的JSON Response,定制化错误信息到Excel

    package ScriptLibrary; import org.json.JSONArray; import org.json.JSONException; import org.json.JSO ...

  7. SoapUI对于Json数据进行属性值获取与传递

    SoapUI的Property Transfer功能可以很好地对接口请求返回的数据进行参数属性获取与传递,但对于Json数据,SoapUI会把数据格式先转换成XML格式,但实际情况却是,转换后的XML ...

  8. How parse REST service JSON response

    1. get JSON responses and go to : http://json2csharp.com/ 2. write data contracts using C# All class ...

  9. [JSON] Validating/Asserting JSON response with Jsonlurper

    import groovy.json.JsonSlurper def response = messageExchange.response.responseContent log.info &quo ...

随机推荐

  1. 解决python3.6的UnicodeEncodeError: 'gbk' codec can't encode character '\xbb' in position 28613: illegal multibyte sequence

    这是python3.6的print()函数自身有限制,不能完全打印所有的unicode字符. 主要的是windows下python的默认编码不是'utf-8',改一下python的默认编码成'utf- ...

  2. java面试技巧

    简历 1.HR看简历,都是看技术关键词.可以多看招聘要求,简历上要多写些关键词.比如io,集合,多线程,并发,spring,mysql,分布式等等. 2.可以准备多份简历,根据不同的jd发送不同的简历 ...

  3. 七:python 对象类型详解三:列表

    一:列表简介: 1,列表可以包含任何种类的对象:数字.字符串甚至集合对象类型.列表都是可变对象,它们都支持在原处修改的操作,可以通过指定的偏移量和分片.列表方法调用.删除语句等方法来实现.关键的作用有 ...

  4. pta l2-4(这是二叉搜索树吗?)

    题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805070971912192 题意:给定n以及n个整数,问该序列 ...

  5. centos6与centos7区别

    CentOS 6 vs CentOS 7的不同   (1)桌面系统[CentOS6] GNOME 2.x[CentOS7] GNOME 3.x(GNOME Shell) (2)文件系统[CentOS6 ...

  6. CardView 卡片布局

    转自:https://www.baidu.com/link?url=WwHvfX3PB_egfQ6GFwxsDeq4NDzB2AW-zaTzskkNXs0qWnIcHyh3pN3Oqe6YO1lAmV ...

  7. Git之清除已保存的账户

    Git会自动保存输入过的用户名.密码. Git的配置文件是-/.gitconfig.可在windows下的GIt Bash.Mac的命令行中,用vim ~/.gitconfig打开. Windows ...

  8. 【git】gitignore

    gitignore git专门有个文件用来管理那些不被纳入版本库的文件,这个文件是 [.gitignore],所有不被包含的都能放进去,但这个是有前提的. 前提 前提是文件如果没被git客户端trac ...

  9. java链接JDBC中的?问题

    String sql = "select * from student where name= ?"; PreparedStatement pst = conn.prepareSt ...

  10. @RequestMapping 和 @GetMapping @PostMapping 区别

      @RequestMapping   和  @GetMapping @PostMapping 区别 @GetMapping是一个组合注解,是@RequestMapping(method = Requ ...