工作中我们经常要两段代码的区别,或者需要查看接口返回的字段与预期是否一致,如何快速定位出两者的差异?除了一些对比的工具比如Beyond Compare、WinMerge等,或者命令工具diff(在linux环境下使用),其实Python中也提供了很多实现对比的库,比如deepdiff和difflib,这两个的区别是deepdiff显示的对比效果比较简洁,但是可以设置忽略的字段,difflib显示的对比结果可以是html的,比较详细。今天我们就学习一下快速实现代码和文件对比的库–deepdiff。
deepdiff
模块常用来校验两个对象是否一致,包含3个常用类,DeepDiff,DeepSearch和DeepHash,其中DeepDiff最常用,可以对字典,可迭代对象,字符串等进行对比,使用递归地查找所有差异。当然,也可以可以用来校验多种文件内容的差异,如txt、json、图片等…
https://github.com/seperman/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
如果对比结果不同,将会给出下面对应的返回:
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'}}}
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}}}
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 WonderWidgets are great', 'Who buys 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://www.iltesting.com/