Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Lists Should Be Equal keyword in Collections should have an option to ignore order #2703

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
bkhouri opened this issue Nov 1, 2017 · 16 comments
Labels
acknowledge To be acknowledged in release notes enhancement good first issue Good for newcomers priority: medium rc 1
Milestone

Comments

@bkhouri
Copy link

bkhouri commented Nov 1, 2017

when comparing lists, we sometimes want to compare only the content irregardless of the order.

Currently, the Lists should be equal ensures each index in the list is the same.

So the following test case fails

*** Settings ***
Library     Collections

*** Test Cases ***
Compare lists
    ${l1}=  create list     a   b    c
    ${l2}=  create list     c   a    b
    lists should be equal   ${l1}   ${l2}

If I wanted to get this test to pass, I would need to use a combination of keywords found in Collections and BuiltIn.

*** Settings ***
Library     Collections

*** Test Cases ***
Compare lists
*** Settings ***
    ${l1}=  create list     a   b    c
    ${l2}=  create list     c   a    b
    list should contain sub list  ${l1}     ${l2}
    ${l1_length}=       get length  ${l1}
    length should be    ${l2}       ${l1_length}

I would be nice to be able to do something as follows:

*** Settings ***
Library     Collections

*** Test Cases ***
Compare lists
    ${l1}=  create list     a   b    c
    ${l2}=  create list     c   a    b
    lists should be equal   ${l1}   ${l2}      ignore_order=True

This ticket has been opened to improve the Lists should be equal keywords to include a way to ignore the orders of the list.

@pekkaklarck
Copy link
Member

Sounds reasonable. What about duplicates?

@bkhouri
Copy link
Author

bkhouri commented Nov 3, 2017

I haven't given some thoughts about duplicates, but I guess we can have an "ignore_duplicates" argument as well.

@bbpatel2001
Copy link
Contributor

bbpatel2001 commented Nov 21, 2017

This Lists should be equal keyword first compares length of two list and if it is not same it fails.
if we have ignore_order=True as argument, we can check first list's element in 2nd list and if it is available at any position, test should pass.

Pseudo code

If  ignore_order=True
    remove duplicates from lists
    Fail if  not same length
    if  element is not available in 2nd list, assert fail.
else  ##  order should be checked 
    compare item1 and item2
if ignore_order == True: 
    assert_true(item1 in list2, msg='Index %d%s' % (index,  " Not in second list"))
else:
    assert_equal(item1, item2, msg='Index %d%s' % (index, name))

As length of both lists are, same we need to check first list's element in 2nd list in case of ignore_order.

@bbpatel2001
Copy link
Contributor

bbpatel2001 commented Nov 22, 2017

Hi @pekkaklarck,
Can you please review following _yield_list_diffs function.
need to import from collections import Counter

def lists_should_be_equal(list1, list2, ignore_order=False,msg=None, values=True,
                              names=None):
    ....
    diffs = list(_yield_list_diffs(list1, list2, names,ignore_order))
   ....

def _yield_list_diffs(list1, list2, names,ignore_order=False):
    **if ignore_order :
        assert_true(Counter(list1) == Counter(list2 ), msg='Lists  are  different')
    else:**
        for index, (item1, item2) in enumerate(zip(list1, list2)):         
            name = ' (%s)' % names[index] if index in names else ''
            try:
                assert_equal(item1, item2, msg='Index %d%s' % (index, name))
            except AssertionError as err:
                yield unic(err)
    ...

If we add these two lines before for loop in the existing given function will compare two UN-ordered lists.

Case 1:
['A', 'B', 'C', 'B']
['A', 'D', 'B', 'B', 'E']
lists_should_be_equal(my_list1,my_list2,ignore_order=True)
AssertionError: Lengths are different: 4 != 5

Case 2:
['A', 'B', 'C', 'B']
['A', 'D', 'B', 'B']
lists_should_be_equal(my_list1,my_list2,ignore_order=True)
AssertionError: Lists are not matching

Case 3:
['A', 'B', 'C', 'B']
['C', 'A', 'B', 'B']

PASS

Adding more tests and verifying it

  • Duplicates not removed and compares correctly.
  • No original list modified.

@bbpatel2001
Copy link
Contributor


Lists Should Be Equal With Different Values Ignore_order :: FAIL L... | PASS |

Lists Should Be Equal With Different Values And Own Error Message ... | PASS |

Lists Should Be Equal With Different Values And Own And Default Er... | PASS |

Lists Should Be Equal With Named Indices As List Ignore_order :: F... | FAIL |
Lists are different:
Index 0 (a): 11 != 13
Index 2 (c): 13 != 11

Lists Should Be Equal With Named Indices As List With Too Few Valu... | PASS |

Lists Should Be Equal With Duplicate Value Ignore_order :: PASS li... | PASS |

Lists Should Be Equal With Duplicate Value Second Small List :: FA... | FAIL |
Lists are different

Lists Should Be Equal With Two Duplicate Value Ignore_order :: FAI... | PASS |

Lists Should Be Equal With Duplicate And Different Value Ignore_or... | FAIL |
Lists are different:
Index 2: A != E
Index 3: D != A

@bbpatel2001
Copy link
Contributor

#2720

@bbpatel2001
Copy link
Contributor

#2720

@pekkaklarck
Copy link
Member

@bbpatel2001, I don't understand the usage of collections.Counter at all. I would assume just sorting lists before comparison would be the easiest solution. Are you interested to look at this again?

@chriscallan
Copy link
Contributor

As Pekka notes, sorting the list contents and comparing those sorted lists is the easiest way to do this, and the way that I've handled this situation in other projects when I only care about list contents rather than order.

@kanchi240
Copy link
Contributor

why not to use the "should be equal" keyword in buildin?

@sebastianciupinski
Copy link

sebastianciupinski commented May 8, 2019

What about introducing Set concept into framework itself and into Collections with related Sets Should Be Equal , Remove From Set, Convert To Set, etc?

For now we have $scalar, @list and &dict, so why not ^set for example? But even without introducing ^set structure, keyword Sets Should Be Equal could also operate on lists, as they can be easily converted to sets.

@pekkaklarck
Copy link
Member

I don't think sets are needed so often that they'd require a separate variable type. Convert To Set and possibly also other set relayed kws could be added to Collections, though. That requires a separate issue (and a PR).

@rainydew
Copy link

rainydew commented Dec 26, 2019

May this one help?
In our company I just extend this library to custom RF library and then import it to compare.
#2717 (comment)

@bbpatel2001
Copy link
Contributor

Hi @pekkaklarck could you please review PR #3469

@bbpatel2001
Copy link
Contributor

is this PR #3469 RF 3.2 candidate?

@pekkaklarck pekkaklarck added this to the v3.2 milestone Feb 15, 2020
@pekkaklarck pekkaklarck added the acknowledge To be acknowledged in release notes label Feb 15, 2020
@pekkaklarck pekkaklarck changed the title "Lists should be equal" keywords in the Collection library should have the option to ignore order Lists Should Be Equal keywords in Collections should have the option to ignore order Feb 28, 2020
pekkaklarck added a commit that referenced this issue Feb 28, 2020
@pekkaklarck pekkaklarck changed the title Lists Should Be Equal keywords in Collections should have the option to ignore order Lists Should Be Equal keywords in Collections should have an option to ignore order Feb 28, 2020
@pekkaklarck
Copy link
Member

This was implemented by PR #3469. Thanks a lot @bbpatel2001!

@pekkaklarck pekkaklarck changed the title Lists Should Be Equal keywords in Collections should have an option to ignore order Lists Should Be Equal keyword in Collections should have an option to ignore order Apr 3, 2020
ngoan1608 pushed a commit to ngoan1608/robotframework that referenced this issue Mar 4, 2021
ngoan1608 pushed a commit to ngoan1608/robotframework that referenced this issue Mar 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
acknowledge To be acknowledged in release notes enhancement good first issue Good for newcomers priority: medium rc 1
Projects
None yet
Development

No branches or pull requests

7 participants