Python中一个非常高效的json对比库–deepdiff

图片[1]-Python中一个非常高效的json对比库–deepdiff-软件测试圈
工作中我们经常要两段代码的区别,或者需要查看接口返回的字段与预期是否一致,如何快速定位出两者的差异?除了一些对比的工具比如Beyond CompareWinMerge等,或者命令工具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()

image-20220715172541928

测试用例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']"}))

更多的参数使用可以,进入源码中查看:

image-20220715183110925

更多关于DeepDiff的使用可以查看下面的文档:

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
相关推荐
  • 暂无相关文章
  • 评论 抢沙发