• 【SoapUI】比较Json response


    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"
    }
    

      

  • 相关阅读:
    <<C++ Primer>> 第三章 字符串, 向量和数组 术语表
    <<C++ Primer>> 第二章 变量和基本类型 术语表
    <<C++ Primer>> 第一章 开始 术语表
    PAT A1077 Kuchiguse (20)
    PAT A1035 Password (20)
    PAT A1005 Spell It Right (20)
    <<C++ Primer>> 术语表 (总) (待补充)
    PAT A1001 A+B Format (20 分)
    PAT B1048 数字加密 (20)
    Protocol
  • 原文地址:https://www.cnblogs.com/MasterMonkInTemple/p/7778212.html
Copyright © 2020-2023  润新知