首頁 > 軟體

Python中高效的json對比庫deepdiff詳解

2022-07-20 14:03:16

工作中我們經常要兩段程式碼的區別,或者需要檢視介面返回的欄位與預期是否一致,如何快速定位出兩者的差異?除了一些對比的工具比如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()

測試用例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/

到此這篇關於Python中高效的json對比庫deepdiff詳解的文章就介紹到這了,更多相關Python json對比庫deepdiff內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com