亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python全字段斷言之DeepDiff模塊詳解

 更新時(shí)間:2023年08月21日 11:34:35   作者:shines_m  
這篇文章主要介紹了Python全字段斷言之DeepDiff模塊詳解,Python中也提供了deepdiff庫,常用來校驗(yàn)兩個(gè)對(duì)象是否一致,包含3個(gè)常用類,DeepDiff,DeepSearch和DeepHash,,需要的朋友可以參考下

一、簡(jiǎn)介

工作中我們經(jīng)常要兩段代碼的區(qū)別,或者需要查看接口返回的字段與預(yù)期是否一致。

Python中也提供了deepdiff庫,常用來校驗(yàn)兩個(gè)對(duì)象是否一致,包含3個(gè)常用類,DeepDiff,DeepSearch和DeepHash

其中DeepDiff最常用,可以對(duì)字典,可迭代對(duì)象,字符串等進(jìn)行對(duì)比,使用遞歸地查找所有差異。

也可以用來校驗(yàn)多種文件內(nèi)容的差異,如txt、json、圖片等…

DeepDiff庫常用來校驗(yàn)兩個(gè)對(duì)象是否一致,并找出其中差異之處。

安裝:

pip install deepdiff

二、DeepDiff模塊

1.deepdiff常用操作

如果實(shí)際請(qǐng)求結(jié)果和預(yù)期值的json數(shù)據(jù)都一致,那么會(huì)返回{}空字典,否則會(huì)返回對(duì)比差異的結(jié)果,接口測(cè)試中我們也可以根據(jù)這個(gè)特點(diǎn)進(jìn)行斷言。

如果對(duì)比結(jié)果不同,將會(huì)給出下面對(duì)應(yīng)的返回:

  • type_changes:類型改變的key
  • values_changed:值發(fā)生變化的key
  • dictionary_item_added:字典key添加
  • dictionary_item_removed:字段key刪除

2.代碼示例

2.1 對(duì)比txt文件

from deepdiff import DeepDiff
# 對(duì)比file文件
f1, f2 = open('./data/a.txt', 'r', encoding='utf-8').read(), open('./data/b.txt', 'r', encoding='utf-8').read()
print(DeepDiff(f1, f2))

輸出:
{'values_changed': {'root': {'new_value': 'abcd', 'old_value': 'abc'}}}

2.2 對(duì)比json

from deepdiff import DeepDiff
# 對(duì)比json文件
json1={
    'code': 0,
    "message": "成功",
    "data": {
    "total": 28,
    "id":123
    }
}
json2={
    'code':0,
    "message":"成功",
    "data": {
    "total": 29,
    }
}
print(DeepDiff(json1, json2))

# 輸出結(jié)果,id移除,total值發(fā)生改變
{'dictionary_item_removed': [root['data']['id']], 'values_changed': {"root['data']['total']": {'new_value': 29, 'old_value': 28}}}

2.3 DeepDiff在Pytest框架中的應(yīng)用

注意,對(duì)比的報(bào)文必須是字典格式?。?!

from deepdiff import DeepDiff
import pytest
import requests
# DeepDiff在Pytest框架中的應(yīng)用, 注意,對(duì)比的報(bào)文必須是字典格式?。?!
class 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):
        # 返回字典格式報(bào)文
        self.response = requests.get('http://www.httpbin.org.json').json()
    def test_case_01(self):
        print('用例對(duì)比結(jié)果:')
        print(DeepDiff(self.response, self.expect))
    def test_case_02(self):
        print('用例對(duì)比結(jié)果:')
        print(DeepDiff(self.response['slideshow']['author'], 'Yours Truly1'))
if __name__ == '__main__':
    pytest.main(['-s'])

輸出:
PASSED                          [ 50%]用例對(duì)比結(jié)果:
{}
PASSED                          [100%]用例對(duì)比結(jié)果:
 {'values_changed': {'root': {'new_value': 'Yours Truly1', 'old_value': 'Yours Truly'}}}

其實(shí),在實(shí)際接口斷言中,可能需要校驗(yàn)的字段順序不一樣,又或者有一些字段值不需要,為了解決這類問題,Deepdiff也提供了相信的參數(shù),只需要在比較的時(shí)候加入,傳入對(duì)應(yīng)參數(shù)即可。

  • 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']"}))

3.參數(shù)介紹

3.1 展示差異的深度

cutoff_distance_for_pairs: (1 >= float > 0,默認(rèn)值=0.3)

此參數(shù)通常結(jié)合ignore_order=true使用,用于結(jié)果中展示差異的深度。

值越大,則結(jié)果中展示的差異深度越大。

from deepdiff import DeepDiff
t1 = [[[1.0]]]
t2 = [[[20.0]]]
print(DeepDiff(t1, t2, ignore_order=True, cutoff_distance_for_pairs=0.3))
print(DeepDiff(t1, t2, ignore_order=True, cutoff_distance_for_pairs=0.2))
print(DeepDiff(t1, t2, ignore_order=True, cutoff_distance_for_pairs=0.1))

輸出:
{'values_changed': {'root[0][0][0]': {'new_value': 20.0, 'old_value': 1.0}}}
{'values_changed': {'root[0][0]': {'new_value': [20.0], 'old_value': [1.0]}}}
{'values_changed': {'root[0]': {'new_value': [[20.0]], 'old_value': [[1.0]]}}}

3.2 ignore types

1)ignore_string_type_changes

默認(rèn)=False,默認(rèn)忽略字符串類型的更改。如果ignore_string_type_changes=True,則b"Hello" 與 “Hello”被認(rèn)為是相同的。

print(DeepDiff(b'hello', 'hello'))
print(DeepDiff(b'hello', 'hello', ignore_string_type_changes=True))

輸出:
{'type_changes': {'root': {'old_type': <class 'bytes'>, 'new_type': <class 'str'>, 'old_value': b'hello', 'new_value': 'hello'}}}
 {}

2)ignore_numeric_type_changes

默認(rèn)=False,表示忽略數(shù)值類型更改。設(shè)置為true時(shí),則認(rèn)為10和10.0是相同的

PS:此參數(shù)僅作用與numbers對(duì)象比較,如果拿numers和string比較則不生效

from deepdiff import DeepDiff
from decimal import Decimal
t1 = Decimal('10.01')
t2 = 10.01
print(DeepDiff(t1, t2))
print(DeepDiff(t1, t2, ignore_numeric_type_changes=True))

輸出:
{'type_changes': {'root': {'old_type': <class 'decimal.Decimal'>, 'new_type': <class 'float'>, 'old_value': Decimal('10.01'), 'new_value': 10.01}}}
 {}

3.3 view

DeepDiff支持對(duì)比結(jié)果選擇text視圖和tree視圖展示。

主要區(qū)別在于, tree視圖具有遍歷對(duì)象的功能,可以看到哪些對(duì)象與哪些其他對(duì)象進(jìn)行了比較。

雖然視圖選項(xiàng)決定了輸出的格式,但無論你選擇哪種視圖,你都可以通過使用pretty()方法得到一個(gè)更適合閱讀的輸出

t1= {"name": "yanan", "pro": {"sh": "shandong", "city": ["zibo", "weifang"]}}
t2 = {"name": "changsha", "pro": {"sh": "shandong", "town": ["taian", "weifang"]}}
ddiff = DeepDiff(t1, t2, view='tree')
print(ddiff)
# 默認(rèn)為text
ddiff = DeepDiff(t1, t2, view='text')
print(ddiff)

輸出:
 {'dictionary_item_added': [<root['pro']['town'] t1:not present, t2:['taian', 'w...]>], 'dictionary_item_removed': [<root['pro']['city'] t1:['zibo', 'we...], t2:not present>], 'values_changed': [<root['name'] t1:'yanan', t2:'changsha'>]}
 {'dictionary_item_added': [root['pro']['town']], 'dictionary_item_removed': [root['pro']['city']], 'values_changed': {"root['name']": {'new_value': 'changsha', 'old_value': 'yanan'}}}

3.4 pretty( ) 方法

使用pretty( ) 方法獲得更可讀的輸出, 無論你使用什么視圖來生成結(jié)果

t1= {"name": "yanan", "pro": {"sh": "shandong", "city": ["zibo", "weifang"]}}
t2 = {"name": "changsha", "pro": {"sh": "shandong", "town": ["taian", "weifang"]}}
print(DeepDiff(t1, t2, view='tree').pretty())
print(DeepDiff(t1, t2, view='text').pretty())

 輸出:
Item root['pro']['town'] added to dictionary.
Item root['pro']['city'] removed from dictionary.
Value of root['name'] changed from "yanan" to "changsha".

Item root['pro']['town'] added to dictionary.
Item root['pro']['city'] removed from dictionary.
Value of root['name'] changed from "yanan" to "changsha".

大家在比較兩個(gè)數(shù)據(jù)對(duì)象的時(shí)候,更多遇到的場(chǎng)景是:key值不同、key新增、key減少、key值類型改變、結(jié)構(gòu)不同

t1 = {
'Author': '河馬',
'wechat': 'ZZ666'
}
t2 = {
'Author': '河馬',
'wechat': 'ZZ666',
'Blog' : 'https://www.hctestedu.com/'
}
t3 = {
'Author': '河馬',
'wechat': 'ZZ777'
}
t4 = {
'Author': '河馬',
'wechat': 777
}
t5 = [{
'Author': '河馬',
'wechat': 'ZZ666'
}]
# Key值不同
print(DeepDiff(t1, t3).pretty())
# Key新增
print(DeepDiff(t1, t2).pretty())
# Key減少
print(DeepDiff(t2, t1).pretty())
# Key值類型改變
print(DeepDiff(t1, t4).pretty())
# 結(jié)構(gòu)不同
print(DeepDiff(t1, t5).pretty())
# Key值相同
result = DeepDiff(t1, t1).pretty()
print(DeepDiff(t1, t1).pretty())
assert "" == result

輸出:
Value of root['wechat'] changed from "ZZ666" to "ZZ777".
Item root['Blog'] added to dictionary.
Item root['Blog'] removed from dictionary.
Type of root['wechat'] changed from str to int and value changed from "ZZ666" to 777.
Type of root changed from dict to list and value changed from {'Author': '展昭', 'wechat': 'ZZ666'} to [{'Author': '展昭', 'wechat': 'ZZ666'}].

三、DeepSearch模塊

該模支持在對(duì)象中搜索對(duì)象。

幾個(gè)重要的參數(shù):

  • use_regexp: 使用正則表達(dá)式,默認(rèn)False。
  • strict_checking:強(qiáng)校驗(yàn),默認(rèn)Ture。為True時(shí),它將檢查要匹配的對(duì)象的類型,因此在搜索 '1234' 時(shí),它將不匹配 int 1234。
  • case_sensitive:為True時(shí),表示大小寫敏感。
from deepdiff import DeepSearch
obj = ["long somewhere", "string", 0, "somewhere great!"]
# 使用正則表達(dá)式
item = "some*"
ds = DeepSearch(obj, item, use_regexp=True)
print(ds)
# 大小寫敏感
item = 'someWhere'
ds = DeepSearch(obj, item, case_sensitive=True)
print(ds)
item = 'some'
ds = DeepSearch(obj, item, case_sensitive=True)
print(ds)
# 強(qiáng)校驗(yàn)
item = 0
ds = DeepSearch(obj, item, strict_checking=True)
print(ds)
item = "0"
ds = DeepSearch(obj, item, strict_checking=True)
print(ds)

輸出:
{'matched_values': ['root[0]', 'root[3]']}
{}
{'matched_values': ['root[0]', 'root[3]']}
{'matched_values': ['root[2]']}
{}

正則表達(dá)式這個(gè)點(diǎn)的應(yīng)用場(chǎng)景比較多,當(dāng)你事先對(duì)預(yù)期結(jié)果的值不能進(jìn)行100%確定時(shí),可以使用正則匹配實(shí)際值進(jìn)行斷言

四、grep模塊

grep是DeepSearch提供的一個(gè)更好用的方法。

它所接受的參數(shù)與DeepSearch完全相同,只是需要你用管道將對(duì)象送入它,而不是將它作為參數(shù)傳遞。

它的工作原理和 linux shell中的grep一樣

from deepdiff import grep
obj = ["long somewhere", "string", 0, "somewhere great!"]
item = "somewhere"
ds = obj | grep(item)
print(ds)

輸出:
{'matched_values': ['root[0]', 'root[3]']}

五、Extract模塊

該模塊可以根據(jù)值抽取其Key的路徑;反過來根據(jù)Key路徑提取其值

from deepdiff import extract
obj = {"a": [{'2': 'b'}, 3], "b": [4, 5]}
# root+鍵名+list下標(biāo)+鍵名
path = "root[a][0]['2']"
print(extract(obj, path))

輸出:
b

到此這篇關(guān)于Python全字段斷言之DeepDiff模塊詳解的文章就介紹到這了,更多相關(guān)Python的DeepDiff模塊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論