【问题标题】:compare json data in Robot framework在 Robot 框架中比较 json 数据
【发布时间】:2021-09-28 23:07:20
【问题描述】:

我在机器人框架问题中有一个比较 json 数据。 如果我有如下三个json:

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
}

这是我想做的:

       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

所以结果为真会显示

{

“状态”:好的,

“型号”:YYY,

“数字”:0000

}

我知道这可能很复杂,但是机器人框架可以有相关的关键字来做到这一点吗? 谢谢!!

暂时附上我的作品:

*** 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}

【问题讨论】:

  • 到目前为止,您为实现目标做了哪些尝试?
  • 你绝对可以在机器人框架中做到这一点,我认为 mutch 更容易的是用 python 编写代码,然后在 rf 中使用它。
  • 由于格式不正确,您在此处附加的脚本将无法运行 - 我想您已经很清楚了,但想指出。我从您的脚本中读到的是,您已经将所有数据放在单独的列表中,但无法创建有效的字典?当前的输出是什么,为什么对您不可用?
  • @Morkkis 我有我需要的所有数据(列表),但我不知道如何比较两个列表然后选择相同的对象并存储到另一个列表。之后,我想使用比较结果列表来检查它是否存在于 json_C

标签: robotframework


【解决方案1】:

JSON 作为字典

您可能希望在 this discussion 上查看答案 - 这不是您要寻找的内容,但具有基础知识。 您可以使用 JSON 从 JSON 创建字典,而不必做这么多额外的工作

${json}=    evaluate    json.loads('''${json_string}''')    json

在此之后,您可以在 Robot Framework 中正常调用字典中的任何值

${status}=    Get From Dictionary    ${json}    Status
# ${status} will now contain string OK

从 JSON 字典中获取项目

为了解决您的问题,您需要为您拥有的每个 JSON 文件创建一个字典,然后比较字典以查找兼容的键。当然json_A 将返回一个列表,因为Properties 键是列表格式,但它不会改变这里的想法。我们将遍历 json_A 提供的列表,然后将列表条目与 json_B 和 json_C 中的键进行比较。你可以考虑关注

*** 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}

以上仅针对 json_A 测试 json_B - 要将 json_C 添加到循环中,只需重复相关关键字即可。

另请注意,如果您希望在同一个 JSON 文件中验证某些嵌套字典,您可以简单地让嵌套字典分隔变量并在那里使用相同的方法。

比较字典项

在同一个 FOR 循环中比较具有相同键的两个字典相当简单。您只需获取单独的键列表或字典,然后遍历键并验证值是否匹配。在这种情况下,Robot 甚至有一个 keyword Dictionaries Should be Equal 可以为您比较长度和键:值对。

如果存在非失败状态的可能性,即字典中存在不相等数量的键,请使用具有较少键的字典进行迭代。如果现在知道这一点,则需要在尝试访问密钥之前验证密钥的存在,否则 Python 将抛出 KeyError。对于这种情况,您可以将以下脚本视为上述脚本的扩展 - FOR 循环的替换。

# 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

【讨论】:

  • 我会按照你说的来试一试。非常感谢您的回答。
  • 顺便说一句,“字典应包含密钥”似乎只能检查是否存在但不返回任何内容。如果我想使用 result = 比较 json_B 和 json_A 和 PICK SAME OBJECT,该怎么做?
  • 是的,该关键字仅返回TrueFail,具体取决于该键是否存在 - 务必检查,因为尝试访问不存在的键会导致 Python 中的 KeyError。如果您希望返回值,您可以使用 Collections Library 中的关键字 Get From Dictionary 或使用 ${dict["key"]} 访问变量,如 User Guide 所示
  • 我已经根据@quickme 的评论调整了答案
  • ${json_C[${key}]} 应该是 ${json_C}[${key}] 无论如何,它对我有用。再次感谢您的帮助。再会! :)
猜你喜欢
  • 2021-11-10
  • 2020-10-27
  • 2011-01-27
  • 2021-11-21
  • 2016-08-23
  • 2022-11-11
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
相关资源
最近更新 更多