quickme
quickme

Reputation: 5

compare json data in Robot framework

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

Answers (1)

Morkkis
Morkkis

Reputation: 495

JSON as a Dictionary

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

Fetching Items from the JSON Dictionary

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.

Comparing Dictionary Items

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

Related Questions