public void AutoTamperResponseBefore(Session oSession) { if (bAutotestEnabled && apiItems != null && oSession.responseCode == 200) { //foreach (MockResponseRules singleRule in rules.Values) //{ // if (oSession.uriContains(singleRule.ApiPattern)) // { // String orgResponseBody = Encoding.UTF8.GetString(oSession.responseBodyBytes); // oSession.responseBodyBytes = Encoding.UTF8.GetBytes(singleRule.MockedResponse(orgResponseBody)); // } //} foreach (XMLApiItem item in apiItems.Values) { if (oSession.uriContains(item.Apiurl) && item.Response.Type == ResponseType.JSON || item.Response.Type == ResponseType.JSON_LIST) { String orgResponseBody = Encoding.UTF8.GetString(oSession.responseBodyBytes); JToken jtResponse = JToken.Parse(orgResponseBody); Dictionary <String, JsonResponseEntry> responseJsonEntry = JsonUtil.analyzeResponseEntry(jtResponse); JsonXMLMatcher matcher = JsonUtil.matchJsonWithXML(responseJsonEntry, item.Response.Items, item.Response.Type == ResponseType.JSON_LIST); item.Response.matchResult = matcher.matchResult; if (matcher.matchResult == JsonXMLMatcher.MatchResult.MATCH) { logger.Log(item.Apiurl + " match result: MATCHED"); } else { if (matcher.matchResult == JsonXMLMatcher.MatchResult.NOT_MATCH) { oSession["ui-backcolor"] = "red"; } logger.Log(item.Apiurl + " match result:" + matcher.matchResultToString() + "\nroot->\n " + matcher.ToString().Replace("\n", "\n ")); } String newResponseBody = JsonUtil.assembleJson(responseJsonEntry).ToString(); String str = Regex.Replace(newResponseBody.Replace(@"\\", @"\"), @"\s *", "").Replace(",\"", ", \"").Replace("\":", "\": "); oSession.responseBodyBytes = Encoding.Default.GetBytes(str); logger.Log("RessembleJson:\n" + str + "\n"); } } } }
static JsonXMLItemMatcher matchJsonEntryWithXMLItem(JsonResponseEntry jsonEntry, XMLResponseItem xmlItem) { String itemKey = xmlItem.ItemName; JsonXMLItemMatcher itemMatcher = new JsonXMLItemMatcher(); switch (jsonEntry.type) { case JsonResponseEntry.ResponseEntryType.DICT: if (xmlItem.Type == ResponseItemType.DICT) { JsonXMLMatcher matcher = matchJsonWithXML(jsonEntry.subEntry, xmlItem.SubItems, false); switch (matcher.matchResult) { case JsonXMLMatcher.MatchResult.LIST_OR_DICT_NULL: itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.DICT_NULL; itemMatcher.strResult = itemKey + "->dict null\n " + matcher.ToString().Replace("\n", "\n "); break; case JsonXMLMatcher.MatchResult.MATCH: itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.DICT_MATCHED; break; case JsonXMLMatcher.MatchResult.MATCH_PARTLY: itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.LIST_OR_DICT_PARTLY_MATCHED; itemMatcher.strResult = itemKey + "-> dict partly match\n " + matcher.ToString().Replace("\n", "\n "); break; case JsonXMLMatcher.MatchResult.NOT_MATCH: itemMatcher.strResult = itemKey + "-> Not match\n " + matcher.ToString().Replace("\n", "\n "); itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.TYPE_NOT_MATCH; break; } } else { itemMatcher.strResult = itemKey + "-> Type not match in xml is " + XMLResponseItemTypeToString(xmlItem.Type) + " but in json is DICT\n"; itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.TYPE_NOT_MATCH; } break; case JsonResponseEntry.ResponseEntryType.DICT_NULL: if (xmlItem.Type == ResponseItemType.DICT) { itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.DICT_NULL; itemMatcher.strResult = itemKey + "-> Dict null\n"; } else { itemMatcher.strResult = itemKey + "-> Type not match in xml is" + XMLResponseItemTypeToString(xmlItem.Type) + "but in json is DICT_NULL\n"; itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.TYPE_NOT_MATCH; } break; case JsonResponseEntry.ResponseEntryType.LIST_ENTRY: if (xmlItem.Type == ResponseItemType.LIST) { JsonXMLMatcher matcher = matchJsonWithXML(jsonEntry.listEntry[0], xmlItem.SubItems, false); switch (matcher.matchResult) { case JsonXMLMatcher.MatchResult.LIST_OR_DICT_NULL: itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.DICT_NULL; itemMatcher.strResult = itemKey + "->list null\n" + matcher.ToString().Replace("\n", "\n "); break; case JsonXMLMatcher.MatchResult.MATCH: itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.DICT_MATCHED; break; case JsonXMLMatcher.MatchResult.MATCH_PARTLY: itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.LIST_OR_DICT_PARTLY_MATCHED; itemMatcher.strResult = itemKey + "-> List partly match\n " + matcher.ToString().Replace("\n", "\n "); break; case JsonXMLMatcher.MatchResult.NOT_MATCH: itemMatcher.strResult = itemKey + "-> Not match\n " + matcher.ToString().Replace("\n", "\n "); itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.TYPE_NOT_MATCH; break; } } else { itemMatcher.strResult = itemKey + "-> Type not match in xml is " + XMLResponseItemTypeToString(xmlItem.Type) + " but in json is LIST_ENTRY\n"; itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.TYPE_NOT_MATCH; } break; case JsonResponseEntry.ResponseEntryType.LIST_STRING: if (xmlItem.Type == ResponseItemType.LIST) { itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.LIST_STRING_MATCHED; } else { itemMatcher.strResult = itemKey + "-> Type not match in xml is " + XMLResponseItemTypeToString(xmlItem.Type) + " but in json is LIST_STRING\n"; itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.TYPE_NOT_MATCH; } break; case JsonResponseEntry.ResponseEntryType.LIST_NULL: if (xmlItem.Type == ResponseItemType.LIST) { itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.LIST_NULL; itemMatcher.strResult = itemKey + "-> List null\n"; } else { itemMatcher.strResult = itemKey + "-> Type not match in xml is " + XMLResponseItemTypeToString(xmlItem.Type) + " but in json is LIST_NULL\n"; itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.TYPE_NOT_MATCH; } break; case JsonResponseEntry.ResponseEntryType.STRING: if (xmlItem.Type == ResponseItemType.STRING) { itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.STRING_MATCHED; } else { itemMatcher.strResult = itemKey + "-> Type not match in xml is " + XMLResponseItemTypeToString(xmlItem.Type) + " but in json is STRING\n"; itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.TYPE_NOT_MATCH; } break; case JsonResponseEntry.ResponseEntryType.INT: if (xmlItem.Type == ResponseItemType.INT) { itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.INT_MATCHED; } else { itemMatcher.strResult = itemKey + "-> Type not match in xml is " + XMLResponseItemTypeToString(xmlItem.Type) + " but in json is INT\n"; itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.TYPE_NOT_MATCH; } break; case JsonResponseEntry.ResponseEntryType.NULL: if (xmlItem.Type == ResponseItemType.INT || xmlItem.Type == ResponseItemType.STRING) { itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.NULL_MATCHED; } else { itemMatcher.strResult = itemKey + "-> Type not match in xml is " + XMLResponseItemTypeToString(xmlItem.Type) + " but in json is NULL\n"; itemMatcher.itemMatchResult = JsonXMLItemMatcher.ItemMatchResult.TYPE_NOT_MATCH; } break; default: break; } if (itemMatcher.itemMatchResult > xmlItem.matchResult) { xmlItem.matchResult = itemMatcher.itemMatchResult; } return(itemMatcher); }
public static JsonXMLMatcher matchJsonWithXML(Dictionary <String, JsonResponseEntry> jsonResponseEntry, Dictionary <String, XMLResponseItem> xmlResponseItems, bool isRootList) { JsonXMLMatcher matcher = new JsonXMLMatcher(); Dictionary <String, XMLResponseItem> xmlResponseItemsCopy = new Dictionary <String, XMLResponseItem>(xmlResponseItems); //如果是List节点需要遍历每一个List内容来判断XML匹配 if (jsonResponseEntry.Count == 1 && jsonResponseEntry.ContainsKey("") && jsonResponseEntry[""].type == JsonResponseEntry.ResponseEntryType.LIST_ENTRY) { if (isRootList) { matcher = matchJsonWithXML(jsonResponseEntry[""].subEntry, xmlResponseItems, false); } else { matcher.matchResult = JsonXMLMatcher.MatchResult.NOT_MATCH; matcher.strResult = "Json type is List but do not match with the XML"; } } else { //遍历每一个json中的数据格式,和XML对比,找到差异和是否有json中多余的部分, //匹配成功则在XML对象中移除相关Key,剩余的便是XML有但是json没有的部分了 foreach (String key in jsonResponseEntry.Keys) { if (xmlResponseItemsCopy.ContainsKey(key)) { JsonXMLItemMatcher result = matchJsonEntryWithXMLItem(jsonResponseEntry[key], xmlResponseItems[key]); matcher.jsonItemMatchStatus.Add(key, result); } else { matcher.jsonEntryNotFound.Add(key); } xmlResponseItemsCopy.Remove(key); } foreach (String key in xmlResponseItemsCopy.Keys) { matcher.xmlEntryNotFound.Add(key); } //处理当前Matcher的匹配结果 int jsonEntryNotFoundCount = matcher.jsonEntryNotFound.Count; int xmlEntryNotFound = matcher.xmlEntryNotFound.Count; //json有没有被覆盖的数据(通常有问题,需要更新XML) if (jsonEntryNotFoundCount > 0) { matcher.matchResult = JsonXMLMatcher.MatchResult.NOT_MATCH; matcher.strResult += "XML has items missing:"; foreach (String key in matcher.jsonEntryNotFound) { matcher.strResult += key + ","; } matcher.strResult += "\n"; } //XML有没有被覆盖到的数据(常见的,定义的规则中是有字段不是必须返回的) else if (xmlEntryNotFound > 0) { matcher.matchResult = JsonXMLMatcher.MatchResult.MATCH_PARTLY; matcher.strResult += "Json has items missing:"; foreach (String key in matcher.xmlEntryNotFound) { matcher.strResult += key + ","; } matcher.strResult += "\n"; } //针对每个匹配的item再做下对比 foreach (String jsonItemKey in matcher.jsonItemMatchStatus.Keys) { JsonXMLItemMatcher result = matcher.jsonItemMatchStatus[jsonItemKey]; switch (result.itemMatchResult) { case JsonXMLItemMatcher.ItemMatchResult.STRING_MATCHED: case JsonXMLItemMatcher.ItemMatchResult.LIST_ENTRY_MATCHED: case JsonXMLItemMatcher.ItemMatchResult.DICT_MATCHED: case JsonXMLItemMatcher.ItemMatchResult.INT_MATCHED: case JsonXMLItemMatcher.ItemMatchResult.NULL_MATCHED: if (matcher.matchResult == JsonXMLMatcher.MatchResult.DEFAULT) { matcher.matchResult = JsonXMLMatcher.MatchResult.MATCH; } break; case JsonXMLItemMatcher.ItemMatchResult.DICT_NULL: if (matcher.matchResult <= JsonXMLMatcher.MatchResult.MATCH) { matcher.matchResult = JsonXMLMatcher.MatchResult.LIST_OR_DICT_NULL; } break; case JsonXMLItemMatcher.ItemMatchResult.LIST_NULL: if (matcher.matchResult <= JsonXMLMatcher.MatchResult.MATCH) { matcher.matchResult = JsonXMLMatcher.MatchResult.LIST_OR_DICT_NULL; } break; case JsonXMLItemMatcher.ItemMatchResult.LIST_OR_DICT_PARTLY_MATCHED: if (matcher.matchResult <= JsonXMLMatcher.MatchResult.MATCH) { matcher.matchResult = JsonXMLMatcher.MatchResult.MATCH_PARTLY; } break; case JsonXMLItemMatcher.ItemMatchResult.TYPE_NOT_MATCH: matcher.matchResult = JsonXMLMatcher.MatchResult.NOT_MATCH; break; default: break; } matcher.strResult += result.ToString(); } xmlResponseItemsCopy = null; } return(matcher); }