Json fault-tolerant data automatic output based on python

original
2020/05/14 08:00
Reading number 138

preface


In the test work, it is often necessary to make fault tolerance for the Json data returned by the server, that is, it is necessary to ensure that when the values in the original data are replaced with abnormal data types, the relevant data transmission and processing systems will not have errors, crashes, and other problems.


If fault tolerant data is written manually, the minor editor believes that there are two drawbacks:

1. Labor and time costs caused by tedious operations;

2. Omission may be caused by too many data;

Therefore, we hope to implement a script that can output all relevant fault tolerant data files with one key according to the Json data to be tested.


summary


Before starting the code implementation, I hope to be clear about the idea. After thinking about it, I establish the script implementation link as follows:

1. Get the key

Obtain the identification of all elements in Json that need data replacement processing (such as each key in the Json object);     

2. Locate value

According to the obtained ID, locate the value to be modified (such as the value corresponding to the key);

3. Replacement and output

Replace each value with data and output it to various fault tolerant data files.


Implementation scheme


1. Get the key


Take such a Json that basically contains all kinds of data as an example:

 {   "testDict" :{   "testDict_1_string" : "1_value" ,   "testDict_2_int" : one ,   "testDict_3_bollen" : false ,   "testDict_4_list" :[ "4_value" , one ],   "testDict_5_null" : null ,   "testDict_6_dict" :{ "6_key" :{ "6_key_1" : "6_value_1" }, "6_list" :[ "test_list" ]},   "testDict_7_complex" :[ {       "id" : "10000" ,       "testA" :{ "A" : "A_value" },       "testB" :[ "B1" , "B2" ] }, {         "id" : "10001" ,       "testC" :{ "C" : "C_value" },       "testRepeat" : "R_value" }, [ "testX" , "testY" , { "testRepeat" : "testRepeat" }], [ "test_list_2" ],       "7_value" ],   "testRepeat" : "R_value" },   "testRepeat" : "R_value" ,   "test_extra" :[ "test_extra_value" ] }


The editor tries to obtain the key by recursion, and thinks about it in the following ways:

1. Different processing methods are required for json objects in dictionary form and json arrays in list form in data;

2. To avoid confusion of duplicate keys, data link structures should be used to distinguish them, such as "parent key child key child key";

3. To avoid confusion between the link structure and the key, special symbols should be used for hierarchical links.

4. In order to avoid duplication of data link structure caused by multiple arrays, an additional "inlist" identifier needs to be added.


The codes are as follows:

 def  getKeyFromJsonFile (dic_json,  keylist, keyParent=None, isChild=False, listInlist=False) :   #If the acquired data type is dict, traverse the key of the dictionary to obtain the value data type   if isinstance(dic_json, dict):     for key in dic_json:       #Do different processing and recursion according to the value data type       if isinstance(dic_json[key], dict):         #Splice the node path and insert the list         if isChild: key = keyParent + '-*-' + key keylist.append(key) getKeyFromJsonFile(dic_json[key.split( '-*-' )[ -1 ]],  keylist, keyParent=key, isChild= True , listInlist= False )       elif isinstance(dic_json[key], list):         if isChild: key = keyParent + '-*-' + key keylist.append(key)         for i in dic_json[key.split( '-*-' )[ -1 ]]: getKeyFromJsonFile(i,  keylist, keyParent=key, isChild= True , listInlist= False )       else :         #The key structure in the list may be the same as that in the list         #It only deals with one layer, but lacks practical significance         if listInlist: key = key + '_*inlist'         if isChild: key = keyParent + '-*-' + key keylist.append(key)   #Recursion is required again for [...] contained in [...]   if isChild and isinstance(dic_json, list):     for i in dic_json:       getKeyFromJsonFile(i, keylist, keyParent=keyParent, isChild= True , listInlist= True )


2. Locate value


The editor tries to divide each key value into a list with the link symbol - * -, and search and locate it level by level in the Json data. At this time, these two situations are considered.


If the value type corresponding to the key value is not a list, the value corresponding to the key value at the end of the link is the value to be modified:

 def  getValue (slist, data_next) :   #Traverse the key parameter after the partition   for j in range( zero ,len(slist)):     #The data type corresponding to the current key is list     if isinstance(data_next[slist[j]], list):       return     #Not a list     if j == len(slist) -1 :       #Get the value to be modified value = data_next[slist[j]]       return     #Retrieve in the next level dictionary in each node path cycle data_next = data_next[slist[j]]


The elements in the list cannot be located according to the key value. You can directly locate them to the list for subsequent traversal:

 def  getValueFromList (data_list, key_list) :   #The element data type in the list is dictionary   if isinstance(data_list, dict):     for key in key_list:       #Retrieve from the passed in key in the dictionary       if key in data_list.keys() and key == key_list[ -1 ]:         #Get the value to be modified value = data_list[key]         #If there is still a list in dict         if isinstance(data_list[key], list):           #Get the target list that needs to traverse its elements to modify value = data_list[key]         return       #Continue recursion if there are child nodes       elif key in data_list.keys(): getValueFromList(data_list[key], key_list)


The logic related to the list in the getValue method should be:

 if  isinstance ( data_next[slist[j]], list ): #The current key has no child nodes   if j == len(slist) -1 :     #Get the target list that needs to traverse its elements to modify     value = data_next[slist[j]]   #Intercept subsequent child nodes to recurse in the list   else :     for datas in data_next[slist[j]]: tlist = slist[j+ one :] getValueFromList(datas, tlist)   return


For the list processing method getValueFromList, the editor also made the following additions (the code will not be repeated here):

1. For the list included in the list, add the judgment isinstance (data_list, list) to continue recursive processing;

2. For the list ID with inlist added, the string needs to be split before traversing the value.


3. Replacement and output


The values to be modified can be replaced by traversing the preset test data list. An example of the list is as follows:

 #Common data types of Json fault tolerance null = None false = False type_list = [ "testString" , one , false , null, [ "test_list" ], { "test_dict" : "test_dict_value" }]


The modified data still points to the original Json data to be tested (the data needs to be restored after each modification and output of the file), and it can be written directly to the file - save each group of data named by the fault tolerance type into a folder named by the data link key value (avoid outputting duplicate data with the same structure):

 #Path is the preset folder path+file name with  open ( path , "w" ) as f: json.dump( data , f, sort_keys= True , indent= four , ensure_ascii= False )


In addition, the default (for example, the key does not exist in the Json data) is also a conventional data fault tolerance method, which can be implemented by deleting the corresponding values from the dictionary and list using the pop () method.


Operation results


To sum up, the fault tolerance file can be obtained by running the script as shown in the figure - for the value to be replaced, each group of fault tolerance data includes int, string, bool and other data types and data defaults



Open any file, as shown in the figure- testA-*-A_int.json, It can be seen that the corresponding value in the original data has been replaced with the preset value:

 //Corresponding position in Json "testDict_7_complex" : [ {                 "id" : "10000" ,                 "testA" : {                     "A" : one },


So far, the goal of outputting Json fault tolerant data files automatically with one click has been achieved. Thanks for reading, welcome to exchange.


Other articles in the python test application series:


Automatic generation of test report based on python









Sogou test WeChat signal: Qa_xiaoming

Sogou test QQ fan group: 459645679


This article is shared from the WeChat official account Sogou QA.
In case of infringement, please contact support@oschina.cn Delete.
Participation in this article“ OSC Source Innovation Plan ”, welcome you to join us and share with us.

Expand to read the full text
Loading
Click to lead the topic 📣 Post and join the discussion 🔥
Reward
zero comment
zero Collection
zero fabulous
 Back to top
Top