robotframework
robotframework copied to clipboard
Collections: Support ignoring order in values when comparing dictionaries
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 : https://github.com/ngoan1608/robotframework/commit/1d852208255d1245cce33a34c700478455cc7298#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.
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?
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.
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?
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.