Reputation: 5
I have a compare json data in Robot framework issue. If I have three json as below:
json_A:
{
"name":"XXX",
"Type": {
"SubType": {
"Properties": [
"Status",
"Model",
"State",
"Tag",
"Number"],
}
}
}
json_B:
{
"Status": OK,
"Model": YYY,
"Number": 0000,
"Task": XYZ
}
json_C:
{
"Status": OK,
"Model": YYY,
"Number": 0000
"State": ON
"Tag": 1234
}
Here are I want to do:
result_A = compare Properties of json_A and Object of json_B and collect SAME object
if "ALL" object of the result_A exist in json_C
is true and print all object key and value
else
break
So the result will be true and it will display
{
"Status": OK,
"Model": YYY,
"Number": 0000
}
I know it might be complicated, but could robot framework has related keyword to do that? Thanks!!
Also attach my work for now:
*** Settings ***
Library JsonValidator
*** Keywords ***
Get_Response_1
[Arguments] ${ip}=${ip}
... ${username}=${USERNAME}
... ${password}=${PASSWORD}
${auth} = Create List ${username} ${password}
Create Session alias=test_session url=http://${ip}:8080/redfish/v1
... auth=${auth} verify=${False}
${response} = GET On Session test_session
... url=https://${ip}:8080/redfish/v1/XXXXXX/YYYYY/ZZZZZ
Status Should Be 200 ${response}
Should Be Equal As Strings OK ${response.reason}
[Return] ${response}
Get_Response_2
[Arguments] ${ip}=${ip}
... ${username}=${USERNAME}
... ${password}=${PASSWORD}
${auth} = Create List ${username} ${password}
Create Session alias=test_session url=http://${ip}:8080/redfish/v1
... auth=${auth} verify=${False}
${response} = GET On Session test_session
... url=https://${ip}:8080/redfish/v1/AAAA/BBBB/CCCC
Status Should Be 200 ${response}
Should Be Equal As Strings OK ${response.reason}
[Return] ${response}
Get_JSON_File_Data
[Documentation] Get_JSON_File_Data
${json}= Get File D:\\xxx\yyy\zzz\\json_A.json
${Properties}= get json value ${json} /Type/SubType/Properties
[Return] ${Properties}
Get_Properties_List
[Documentation] Get_Properties_List
[Arguments] ${GET_RESPONSE_DATA}
${reponse_content}= Parse Json ${GET_RESPONSE_DATA.content}
log ${reponse_content}
FOR ${properties} IN @{reponse_content}
${elements}= get elements ${reponse_content} ${properties}
${properties_list}= create dictionary ${properties} ${elements}
Log ${elements}
Log ${properties}
Log ${properties_list}
END
[Return] ${properties_list}
*** Test Cases ***
${Properties}= Get_JSON_File_Data
log ${Properties}
${GET_JSON_RESPONSE_1}= GET_Response_1
log ${GET_JSON_RESPONSE_1.content}
${properties_list}= Get_Properties_List ${GET_JSON_RESPONSE_1}
Log ${properties_list}
${GET_JSON_RESPONSE_2}= GET_Response_2
Log ${GET_JSON_RESPONSE_2.content}
${properties_list}= Get_Properties_List ${GET_JSON_RESPONSE_2}
Upvotes: 0
Views: 4162
Reputation: 495
You may want to see the answers on this discussion - It's not exactly what you are looking for but has the basics. Instead of having to do so much extra work you can create a dictionary from a JSON by using
${json}= evaluate json.loads('''${json_string}''') json
After this you can call any value from the dictionary normally in Robot Framework
${status}= Get From Dictionary ${json} Status
# ${status} will now contain string OK
To solve your problem, you'll then need to create a dictionary for each JSON file you have and then compare the dictionaries for compatible keys. Of course the json_A
will return a list, as the Properties
key is in list format but it doesn't change the idea here. We'll be iterating through the list provided by json_A and then comparing the list entries with keys inside json_B and json_C. You may consider following
*** Test Cases ***
Compare JSON File Contents
# First get each JSON File in a dictionary
${file}= Get File D:\\xxx\yyy\zzz\\json_A.json
${json_A_full}= evaluate json.loads('''${file}''') json
${file}= Get File <path\\to\\json_B.json>
${json_B}= evaluate json.loads('''${file}''') json
# Because in JSON A the properties key contains a list instead of dictionary, we'll need to get the list as a dictionary
${json_A}= Get From Dictionary ${json_A_full} Properties
# Now we have two variables where
# ${json_A} == [ "Status", "Model", "State", "Tag", "Number"]
# ${json_B} == { "Status": OK, "Model": YYY, "Number": 0000, "Task": XYZ }
# Iterating through list ${json_A} let's us know if all keys are present in dictionary ${json_B}
# Let's create a temp dictionary where we collect the matching keys
&{returnDict}= Create Dictionary
FOR ${item} IN @{json_A}
${key_exist}= Run Keyword and Return Status Dictionary Should Contain Key ${json_B} ${item}
IF '${key_exist}'=='False'
Log Key ${item} not found from json_B!
ELSE
Log Key ${item} found in json_B with value ${json_B[${item}]}
# You can return the key from json_B by simply setting a new variable for it
Set to Dictionary ${returnDict} ${item}=${json_B[${item}]}
END
END
# The returnDict contents should now have each key and value that were matching between json_A and json_B
Log ${returnDict}
Now this above only tests for json_B against json_A - To add json_C to the loop, simply repeat the relevant keywords.
Notice also that if you wish to validate certain nested dictionaries within the same JSON file, you can simply get the nested dictionaries to separate variables and use this same approach there as well.
It is fairly simple to compare two dictionaries with same keys over in a same FOR loop. You'll simply take either a separate list of keys or the dictionaries and iterate over the keys and validate that the values match. For this case Robot has even a keyword Dictionaries Should be Equal
which will make the comparison for you for both length and key:value pairs.
If there is a non-failing state possibility that there are not equal number of keys present in the dictionaries, use the dictionary with less keys to iterate with. If that is now known, you'll need to verify the existence of a key before attempting to access it or there will be KeyError
thrown by the Python. For that case you can consider below script as an extension the the script above - Replacement for the FOR loop.
# JSON Files are parsed to dictionaries and list
# @{json_A}, &{json_B}, &{json_C}
FOR ${key} IN @{json_A}
# Skip validation where either C or B files do not contain same key
${B_exist}= Run Keyword and Return Status Dictionary Should Contain Key ${json_B} ${item}
${C_exist}= Run Keyword and Return Status Dictionary Should Contain Key ${json_C} ${item}
Continue For Loop If '${B_exist}'=='False' or '${C_exist}'=='False'
# Simply validating the keys contain same value in both dictionaries
Should Be Equal ${json_B[${key}]} ${json_C[${key}]}
END
Upvotes: 3