Python - deepdiff校验两个对象是否一致

DeepDiff模块常用来校验两个对象是否一致,并找出其中差异之处,它提供了:

  • DeepDiff:字典,可迭代项,字符串和其他对象的深层差异。它将递归地查找所有更改。
  • DeepSearch:在其他对象中搜索对象。
  • DeepHash:根据对象的内容对其进行哈希处理。

 

DeepDiff#

DeepDiff可以用来校验多种类型的文件内容,如txt、json、图片等......

校验: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'}}}

校验:json文件
a.json文件内容:

{
  "title": "V2EX",
  "slogan": "way to explore",
  "description": "创意工作者们的社区",
  "domain": {
    "url": "www.v2ex.com",
    "host": "8080"
  },
  "data": [{"id":"5e4fa8531225c9423dcda9d8","author_id":"51f0f267f4963ade0e08f503","tab":"share"}, {"id":"5e16978581adfe260207a8c1","author_id":"54009f5ccd66f2eb37190485","tab":"share"}]
}
View Code

b.json文件内容:

{
  "title": "2VEX",
  "slogan": "way to explore",
  "description": "创意工作者们的社区",
  "domain": {
    "url": "www.v2ex.com",
    "host": "8080"
  },
  "data": [{"id":"5e4fa8531225c9423dcda9d8","tab":"share"}, {"id":"5e16978581adfe260207a8c1","author_id":"54009f5ccd66f2eb37190485","tab":"share_we"}]
}
View Code
import json
from deepdiff import DeepDiff
f1, f2 = json.loads(open('a.json', 'r', encoding='utf-8').read()), json.loads(open('b.json', 'r', encoding='utf-8').read())
print(DeepDiff(f1, f2))  
"""  对比结果
{
    'dictionary_item_removed': [root['data'][0]['author_id']], 
    'values_changed': {
        "root['data'][1]['tab']": {
            'new_value': 'share_we', 
            'old_value': 'share'
        }, 
        "root['title']": {
            'new_value': '2VEX', 
            'old_value': 'V2EX'
        }
    }
}
"""

校验字典

from deepdiff import DeepDiff

t1 = {1:1, 3: 3, 4: 4}
t2 = {1:1, 3: 3, 5: 5, 6: 6}
print(DeepDiff(t1, t2))  # {'dictionary_item_added': [root[5], root[6]], 'dictionary_item_removed': [root[4]]}
print(DeepDiff(t1, t2, view='tree'))  # {'dictionary_item_removed': [<root[4] t1:4, t2:not present>], 'dictionary_item_added': [<root[5] t1:not present, t2:5>, <root[6] t1:not present, t2:6>]}

DeepDiff在单元测试中的应用

先来个unittest框架示例:

import unittest
import requests
from deepdiff import DeepDiff


class MyCase(unittest.TestCase):
    expect = {
        "title": "V2EX",
        "slogan": "way to explore",
        "description": "创意工作者们的社区",
        "domain": "www.v2ex.com"
    }

    @classmethod
    def setUpClass(cls):
        cls.response = requests.get('https://www.v2ex.com/api/site/info.json').json()

    def test_case_01(self):
        self.assertEqual(DeepDiff(self.response, self.expect), {})

    def test_case_02(self):
        self.assertEqual(DeepDiff(self.response['title'], 'v2ex'), {})
        """
        AssertionError: {'values_changed': {'root': {'new_value': 'v2ex', 'old_value': 'V2EX'}}} != {}
        """

if __name__ == '__main__':
    unittest.main()

由于实际的请求结果和预期值的json数据都一致,所以DeepDiff返回空字典,然后断言成功;而第二个用例我们修改预期值的title字段值,所以,DeepDiff返回了对比后的结果,与预期值不符,断言失败。
pytest框架中的使用套路是一样的:

import pytest
import requests
from deepdiff import DeepDiff

class TestCase(object):
    expect = {
        "title": "V2EX",
        "slogan": "way to explore",
        "description": "创意工作者们的社区",
        "domain": "www.v2ex.com"
    }

    def setup_class(self):
        self.response = requests.get('https://www.v2ex.com/api/site/info.json').json()

    def test_case_01(self):
        assert not DeepDiff(self.response, self.expect)

    def test_case_02(self):
        assert not DeepDiff(self.response['title'], 'v2ex')
        """
        self = <temp.TestCase object at 0x00000272F7B6FE10>

            def test_case_02(self):
        >       assert not DeepDiff(self.response['title'], 'v2ex')
        
                AssertionError: {'values_changed': {'root': {'new_value': 'v2ex', 'old_value': 'V2EX'}}} != {}
        E       AssertionError: assert not {'values_changed': {'root': {'new_value': 'v2ex', 'old_value': 'V2EX'}}}
        E        +  where {'values_changed': {'root': {'new_value': 'v2ex', 'old_value': 'V2EX'}}} = DeepDiff('V2EX', 'v2ex')
        
        temp.py:104: AssertionError
        """

if __name__ == '__main__':
    pytest.main(['-v', __file__])

参考学习链接:https://www.cnblogs.com/Neeo/articles/12785493.html

posted @ 2021-11-14 13:08  小L小  阅读(364)  评论(0)    收藏  举报