Python json对比库deepdiff
程序员吾非同 人气:0工作中我们经常要两段代码的区别,或者需要查看接口返回的字段与预期是否一致,如何快速定位出两者的差异?除了一些对比的工具比如Beyond Compare、WinMerge等,或者命令工具diff(在linux环境下使用),其实Python中也提供了很多实现对比的库,比如deepdiff和difflib,这两个的区别是deepdiff显示的对比效果比较简洁,但是可以设置忽略的字段,difflib显示的对比结果可以是html的,比较详细。今天我们就学习一下快速实现代码和文件对比的库–deepdiff。
deepdiff是什么
deepdiff
模块常用来校验两个对象是否一致,包含3个常用类,DeepDiff,DeepSearch和DeepHash,其中DeepDiff最常用,可以对字典,可迭代对象,字符串等进行对比,使用递归地查找所有差异。当然,也可以可以用来校验多种文件内容的差异,如txt、json、图片等…
https://github.com/seperman/deepdiff
deepdiff安装
pip install deepdiff
如果实际请求结果和预期值的json数据都一致,那么会返回{}空字典,否则会返回对比差异的结果,接口测试中我们也可以根据这个特点进行断言。
导入
>>> from deepdiff import DeepDiff # For Deep Difference of 2 objects >>> from deepdiff import grep, DeepSearch # For finding if item exists in an object >>> from deepdiff import DeepHash # For hashing objects based on their contents
如果对比结果不同,将会给出下面对应的返回:
- 1、type_changes:类型改变的key
- 2、values_changed:值发生变化的key
- 3、dictionary_item_added:字典key添加
- 4、dictionary_item_removed:字段key删除
案例1、对比txt文件
from deepdiff import DeepDiff """ a.txt的内容是: abc b.txt的内容是: abcd """ f1, f2 = open('a.txt', 'r', encoding='utf-8').read(), open('b.txt', 'r', encoding='utf-8').read() print(DeepDiff(f1, f2)) # 输出结果,内容值发生变化 {'values_changed': {'root': {'new_value': 'abcd', 'old_value': 'abc'}}}
案例2、对比json
from deepdiff import DeepDiff json1={ 'code': 0, "message": "成功", "data": { "total": 28, "id":123 } } json2={ 'code':0, "message":"成功", "data": { "total": 29, } } print(DeepDiff(json1,json2)) # 输出结果,id移除,total值发生改变 #{'dictionary_item_removed': [root['data']['id']], 'values_changed': {"root['data']['total']": {'new_value': 29, 'old_value': 28}}}
DeepDiff在单元测试中的应用
import unittest import requests from deepdiff import DeepDiff class MyCase(unittest.TestCase): expect = { 'slideshow': { 'author': 'Yours Truly', 'date': 'date of publication', 'slides': [{ 'title': 'Wake up to WonderWidgets!', 'type': 'all' }, { 'items': ['Why <em>WonderWidgets</em> are great', 'Who <em>buys</em> WonderWidgets'], 'title': 'Overview', 'type': 'all' }], 'title': 'Sample Slide Show' } } def setUp(self): self.response = requests.get('http://www.httpbin.org/json').json() print(self.response) def test_case_01(self): print(DeepDiff(self.response, self.expect)) def test_case_02(self): print(DeepDiff(self.response['slideshow']['author'], 'Yours Truly1')) if __name__ == '__main__': unittest.main()
测试用例1实际返回和预期结果json完全一样,输出结果为:{},即两者没有差异。
测试用例2断言返回author与期望值,值发生变化。
其实,在实际接口断言中,可能需要校验的字段顺序不一样,又或者有一些字段值不需要,为了解决这类问题,Deepdiff也提供了相信的参数,只需要在比较的时候加入,传入对应参数即可。
ignore order
(忽略排序)ignore string case
(忽略大小写)exclude_paths
排除指定的字段
print(DeepDiff(self.response, self.expect,view='tree',ignore_order=True,ignore_string_case=True,exclude_paths={"root['slideshow']['date']"}))
更多的参数使用可以,进入源码中查看:
更多关于DeepDiff的使用可以查看下面的文档:
https://zepworks.com/deepdiff/5.8.2/diff.html
https://zepworks.com/deepdiff/5.8.2/
https://zepworks.com/tags/deepdiff/
加载全部内容