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

本文介绍了Python的DeepDiff库,用于比较对象、字典、字符串等内容的差异,包括类型变化、值变化、字典项增删等。通过案例展示了如何对比TXT文件和JSON数据,并在单元测试中使用DeepDiff进行断言。此外,还提到了DeepDiff的参数如ignore_order、ignore_string_case和exclude_paths,以适应不同的比较需求。
摘要由CSDN通过智能技术生成

工作中我们经常要两段代码的区别,或者需要查看接口返回的字段与预期是否一致,如何快速定位出两者的差异?除了一些对比的工具比如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的使用可以查看下面的文档:

  • https://zepworks.com/deepdiff/5.8.2/diff.html
  • https://zepworks.com/deepdiff/5.8.2/
  • https://zepworks.com/tags/deepdiff/

更多软件测试资料可以访问我的个人网站:https://www.iltesting.com/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员吾非同

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值