Skip to content

Collections: Support ignoring order in values when comparing dictionaries #5007

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
newedgex opened this issue Jan 9, 2024 · 6 comments · Fixed by #5220
Closed

Collections: Support ignoring order in values when comparing dictionaries #5007

newedgex opened this issue Jan 9, 2024 · 6 comments · Fixed by #5220

Comments

@newedgex
Copy link

newedgex commented Jan 9, 2024

Currently https://github.com/robotframework/robotframework/blob/master/src/robot/libraries/Collections.py#L839 we are missing out on ignore_order already done for

    def lists_should_be_equal(self, list1, list2, msg=None, values=True,
                              names=None, ignore_order=False, ignore_case=False):

Ref : ngoan1608@1d85220#diff-0bb57664ba32d4e2b91c6435cf0b867d630c2db282af83004073303030775bd1

Adding as well ignore_key would be much appreciated since we might deal with ID's and timestamps, and in such cases those keys are to be ignored.

@pekkaklarck
Copy link
Member

Although Python nowadays preserves dictionary order, the order doesn't generally affect equality and it shouldn't matter with this keyword either. Do you have a concrete example where ignore_order would be needed?

ignore_keys could be added for consistency with Dictionaries Should Be Equal. I consider it very low priority, though, because with Dictionary Should Contain Sub Dictionary the second dictionary doesn't need to contain all keys that the first dictionary contain in the first place. If there's a key you'd like to ignore, you can easily remove it from the second dictionary already now. Alternatively you can use Dictionaries Should Be Equal that already supports ignore_keys. Do you have examples where ignore_keys with Dictionary Should Contain Sub Dictionary would be convenient?

If we agree adding this functionality would be a good idea, can you provide a pull request implementing it?

@newedgex
Copy link
Author

newedgex commented Jan 10, 2024

In my case I'm querying an API (fastapi) where item order (in case of lists) and key order (in case of dictionaries) is not enforced.

The DUT , after a reboot will give a different order making the test very brittle and causing it to fail.
Example :

Get the safesearch created profile by ID
    API GET dictionary request comparing the response  ${ROOT}    webfilter/api/v1/config/profiles/1    ${POST_PROFILE_SAFESEARCH_RESPONSE}
API GET dictionary request comparing the response
    [Documentation]       It makes a GET request to the specific baseurl and endpoint and compares the API response (should be a dictionary!) 
    ...                   to another dictionary defined in (json_response). 
    [Arguments]    ${baseurl}    ${endpoint}    ${json_response}
    ${url}=    Set Variable    ${baseurl}${endpoint}
    ${response}=    GET On Session   url=${url}    alias=get_login 
    ${API_SERVER_RESPONSE_HEADERS}=    Create Dictionary    Server    uvicorn    content-type    application/json    X-Robots-Tag    noindex, nofollow    Connection    Keep-Alive
    Dictionary Should Contain Sub Dictionary    ${response.headers}    ${API_SERVER_RESPONSE_HEADERS}
    Should Be Equal As Strings    ${response.status_code}    200
    Run Keyword If    '${response.status_code}' != '200'    Log Variables
    ${evaluated_response}    Evaluate    json.loads('''${json_response}''')
    Dictionary Should Contain Sub Dictionary    ${response.json()}    ${evaluated_response}
    Should Be Equal As Strings    ${response.reason}    OK

This is the error that I'm getting :

Get the safesearch created profile by ID                              | FAIL |
Following keys have different values:
Key safesearch: ['DUCKDUCKGO', 'GOOGLE', 'BING'] != ['DUCKDUCKGO', 'BING', 'GOOGLE']

This is the request / var ${POST_PROFILE_SAFESEARCH_RESPONSE}

 {"id":null,"antivirus":true,"blacklist":[],"allowed_domains":[],"blocked_domains":[],"safesearch":["GOOGLE","DUCKDUCKGO","BING"],"name":"safesearch"}

So basically the API might return different orders for the search engines.

In this case ignore_order would be needed.

If we agree adding this functionality would be a good idea, can you provide a pull request implementing it?

I would love to and would have already done it but I don't have the right confidence with python.

@pekkaklarck
Copy link
Member

So you don't want to ignore order of dictionary keys but instead want to ignore order in their values? I guess something like ignore_value_order could be added, but I don't consider it too high priority. It should be added to Dictionaries Should Be Equal as well.

Is there a reason you couldn't get those values and use Lists Should Be Equal that already supports ignoring order?

@newedgex
Copy link
Author

So you don't want to ignore order of dictionary keys but instead want to ignore order in their values?

Exactly, and yes ignore_value_order would be appropriate.
As for Lists Should Be Equal I can confirm that it works (even without adding ignore_order=True and it seems that by default it ignores the order of the values which in my case is appreciated.
Thanks allot for the quick replies and even more for providing a tool like Robot Framewok, I truly mean it.

@newedgex newedgex changed the title Dictionary Should Contain Sub Dictionary is missing ignore_order and ignore_key Dictionary Should Contain Sub Dictionary is missing ignore_value_order Jan 10, 2024
@pekkaklarck pekkaklarck changed the title Dictionary Should Contain Sub Dictionary is missing ignore_value_order Collections: Support ignoring order in values when comparing dictionaries Sep 25, 2024
@pekkaklarck pekkaklarck added this to the v7.2 milestone Sep 25, 2024
@pekkaklarck
Copy link
Member

We got PR #5220 implementing this. It looks good but I cannot review it properly now. I added this issue to RF 7.2 scope and review it later.

@pekkaklarck
Copy link
Member

I finally got PR #5220 reviewed. It has an unrelated change to sorting unsortable items which should be removed (and possibly added as part of a separate issue and PR), but it looks very good otherwise.

pekkaklarck pushed a commit that referenced this issue Nov 11, 2024
#5220)

Fixes #5007.

---------

Co-authored-by: Marcin Gmurczyk <mgmuras@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants