import json
class JsonCompare:
def __init__(self, new_json, old_json, debug_model=False):
"""
用于两个json串比对,输出两串json字段差异
:param new_json: 用于比对的新json
:param old_json: 基准json
:param debug_model: 为True时将在控制台输出比对结果,默认不开启
"""
self.compare_result = [] # 存放字段差异
self.compare_error = [] # 存放字段比对异常
self.compare(new_json, old_json)
if debug_model:
for i in self.compare_result:
print(i)
for i in self.compare_error:
print(i)
def compare(self, new_json, old_json, path=''):
try:
if not isinstance(new_json, (list, tuple, dict)):
# 比对非list\tuple\dict类型的数据
if not new_json == old_json:
msg = {
'field': path,
'error_type': 'field value diff',
'new json': new_json,
'old json': old_json
}
self.compare_result.append(msg)
elif isinstance(new_json, (list, tuple)):
# 如果新数据是list/tuple,则判断老数据是否类型一致;不一致则追加到compare_error
if type(new_json) != type(old_json):
msg = {
'field': path,
'error_type': "field type diff",
'new json': f"type is {type(new_json)}",
'old json': f"type is {type(old_json)}"
}
self.compare_result.append(msg)
return
if len(new_json) != len(old_json):
msg = {
'field': path,
'error_type': "field indexLength diff",
'new json': f"Length of list is {len(new_json)}",
'old json': f"Length of list is {len(old_json)}"
}
self.compare_result.append(msg)
for index, value in enumerate(new_json):
try:
if index < len(old_json):
self.compare(
value, old_json[index], f'{path}->{index}')
else:
self.compare(value, {}, f'{path}->{index}')
except Exception as e:
self.compare_error.append(
f'Unknown error: {e.args}')
else:
# 比对值为dict类型数据
if not isinstance(old_json, dict):
msg = {
'field': path,
'error_type': "field type diff",
'new json': f"type is {type(new_json)}",
'old json': f"type is {type(old_json)}"
}
self.compare_result.append(msg)
return
new_keys = set(new_json.keys())
old_keys = set(old_json.keys())
diff_keys = old_keys - new_keys # 用于检查老数据存在某个key,但新数据不存在。
for key, value in new_json.items():
try:
if key in old_json.keys():
self.compare(
value, old_json[key], f"{path}->{key}")
else:
msg = {
'field': f"{path}->{key}",
'error_type': 'field missing',
'new json': value,
'old json': f"Field of '{key}' is not exists"
}
self.compare_result.append(msg)
except Exception as e:
self.compare_error.append(
f'Unknown error:{e.args}')
if diff_keys:
for key in diff_keys:
msg = {
'field': f"{path}->{key}",
'error_type': 'field missing',
'new json': f"Field of '{key}' is not exists",
'old json': old_json[key]
}
self.compare_result.append(msg)
except Exception as e:
self.compare_error.append(
f'Unknown error:{e.args}')
"""
测试数据
_old_json = {
"key1": "value1",
"key2": "value2",
"key3": [1],
"object": {
"object_key1": "object_value2",
"object_key2": {
"sub_key": "object_key2_sub_value",
"sub_key4": "object_key2_sub_value"
},
"object_key3": [
{"list_sub_key1": "xx1"},
{"list_sub_key2": "xx"}
]
},
"x": 1.2
}
new_json = {
"key1": "value1",
"key2": "value2",
"key3": (1,),
"object": {
"object_key1": "object_value1",
"object_key2": {
"sub_key": "object_key2_sub_value",
"sub_key2": {"xx": 1}
},
"object_key3": [
{"list_sub_key1": "xx"},
{"list_sub_key2": []}
]
},
"x": 1.2
}
"""
if __name__=="__main__":
old_json_file = "feature_22.1.0.100_release_e2e_0120_russia.json"
new_json_file="feature_22.1.0.100_release_e2e_0120_russia02.json"
with open(old_json_file,encoding="utf-8") as f1:
old_json_data = json.loads(f1.read())
with open("feature_22.1.0.100_release_e2e_0120_russia02.json",encoding="utf-8") as f2:
new_json_data = json.loads(f2.read())
JsonCompare(new_json_data, old_json_data, debug_model=True)