最近在搞接口測試的時候發現了一個比較有趣的json入參數,結構如下:
json = {"aa": "33", "bb": [{"gg": "33"}, {"jj": [{"gg": "33"}, {"haha": [{"gg": "33"}, {"yyyu": [{"yy": "希望調試成功", "kk": {"uu": "hr", "lll": {"gg": "33"}}}]}]}]}], "gg": "33"}
觀察該json數據,我們發現有大量的相同的key(gg),並且這些key的value值都是一樣的,那么我們需要修改所有key(gg)的值,應該怎么做呢?
提問:為什么會有這么有趣的入參數據?
我也不知道,因為公司的出庫單的業務數據就有這么可怕和奇葩的數據,只是沒有本文中舉例的那么誇張
第一:我們可以把這個數據封裝成一個函數,實現如下所示:
def data(gg): dict_data = {'aa': '33', 'bb': [{'gg': gg}, {'jj': [{'gg': gg}, { 'haha': [{'gg': gg}, {'yyyu': [{'yy': '希望調試成功', 'kk': {'uu': 'hr', 'lll': {'gg': gg}}}]}]}]}], 'gg': gg} return dict_data print(data('hahaha'))
這樣很完美的解決我們的問題了。完美,解題結束......enenen、但是這會引生出另一個問題,就是每次接口改動需要去修改代碼,不便於工具化(雖然在接口自動化后接口不太可能會發生改動),
對於測試來說不可能人人都去搞工具化,但是你不能沒有一個工具化的心。
OK,目標明確了,那么我們需要搞個好的思路了,但是在這之前我們不得不先了解一下python對於字典的操作:
首先,最簡單的方法是直接創建字典,dict={"name":"張三","age":"23"}
再次,先創建一個空字典,然后對字典進行賦值或者修改,具體如下圖所示:
從上圖中可以看出,我們是可以直接對字典進行操作的結構為dict["key"] = value,dict["key"] 表示字典的key,value表示key的值,簡單點說就是字典里面的元素,
以及元素的值是什么,但是有一點要清楚,字典里面key的值它可以是一個字符串,可以是數字,可以是列表,可以是字典。(說明:在python中json串可以理解是一個字典)。
不難理解,我們在上圖中直接對一個空字典定義了元素和元素值,那么對嵌套字典改如何進行操作呢?這里以比較有趣的json入參數來進行講解:
如上圖所示,每一個需要修改的key都需要指明路徑,所以非常麻煩,非常難搞,隨着明細的增加,說不定形同名稱的key還會更多,然后有需要手動指明,
這種方法還不如用函數去修改key的值,所以還需要再想想辦法。
想不到更多的表達語言,直接看如下代碼:
dict_data = {'aa': '33', 'bb': [{'gg': ''}, {'jj': [{'gg': 'gg'}, { 'haha': [{'gg': 'gg'}, {'yyyu': [{'yy': '希望調試成功', 'kk': {'uu': 'hr', 'lll': {'gg': 'gg'}}}]}]}]}], 'gg': 'gg'} key = 'gg' def update(key,dict_data): #判斷需要修改的key是否在初始字典中,在則修改 if key in dict_data: #將key為'gg'的值修改成'張三' dict_data[key]='張三' #print(dict_data) #循環字典獲取到所有的key值和value值 for keys,values in dict_data.items(): #判斷valus值是否為列表或者元祖 if isinstance(values,(list,tuple)): #循環獲取列表中的值 for i in values: #判斷需要修改的值是否在上一個循環出的結果中,在則修改 if key in i and isinstance(i,dict): #調用自身修改函數,將key的值修改成'張三' update(key,i) else: #否者則調用獲取value函數 get_value(i) elif isinstance(values,dict): if key in values: update(key,values) else: for keys,values in values.items(): if isinstance(values,dict): update(key, values) else: #循環獲取原始字典的values值 for keys,values in dict_data.items(): #判斷values值是否是列表或者元祖 if isinstance(values,(list,tuple)): #如果是列表或者元祖則循環獲取里面的元素值 for i in values: #判斷需要修改的key是否在元素中 if key in i: #調用修改函數修改key的值 update(key,i) else: #否則調用獲取values的值函數 get_value(i) #判斷values值是否為字典 elif isinstance(values,dict): #判斷需要修改的key是否在values中 if key in values: #調用修改函數修改key的值 update(key,values) else: #獲取values值的函數 get_value(values) return dict_data def get_value(tt): #循環獲取values的值 for values in tt.values(): #判斷循環出的value的值是否為列表或者元祖 if isinstance(values, (list,tuple)): #如果為列表或者元祖則循環獲取列表或者元祖中的值 for i in values: #判斷需要修改的值是否在循環出的值中,且i為字典 if key in i and isinstance(i,dict): #調用修改函數,將key的值修改為'張三' update(key, i) else: #否則調用獲取value函數 get_value(i) elif isinstance(values,dict): if key in values: update(key, values) else: get_value(values) update(key,dict_data)
如上圖代碼所示:總的來說就是將字典循環判斷曲直並修改,然后就完事了咯。
這樣做的好處是,我們在做接口自動化的時候可以將數據與腳本分離,只需在excel中維護好入參,指定獲取返回變量值即可