Issue 9977: TestCase.assertItemsEqual's description of differences (original) (raw)
TestCase.assertItemsEqual uses two different techniques to describe the differences in the inputs that it compares.
If the inputs are sortable, it sorts them and then uses assertSequenceEqual to describe the difference between them considered as ordered sequences.
Otherwise, it uses unittest.util.unorderable_list_difference, which is essentially a multiset comparison.
In practice, I think the output from unorderable_list_difference is usually more readable, so I wonder if something of that kind should be made the default.
Example:
a = [('b', (2, 3)), ('w', (3, 4))] b = [('x', (2, 3)), ('w', (3, 4))] case.assertItemsEqual(a, b)
unorderable_list_difference gives
Expected, but missing: [('b', (2, 3))] Unexpected, but present: [('x', (2, 3))]
while the current assertItemsEqual gives
Sequences differ: [('b', (2, 3)), ('w', (3, 4))] != [('w', (3, 4)), ('x', (2, 3))]
First differing element 0: ('b', (2, 3)) ('w', (3, 4))
- [('b', (2, 3)), ('w', (3, 4))]
- [('w', (3, 4)), ('x', (2, 3))]
In general, I think that the 'first differing element' paragraph that assertSequenceEqual produces is as likely to be misleading as it is to be helpful (when we're really comparing unordered sequences).
If I understand correctly, you are requesting that .assertItemsEqual only use the 2nd (multiset comparison) method, so that if one want the first method, one should directly call .assertSequenceEqual(sorted(a), sorted(b)).
This seems reasonable to me, but I do not use the unittest module, and I suspect others want the implicit call.
In Python 3.2 assertItemsEqual has been replaced with assertCountEqual that has a completely different implementation and error format. The implementation and error output will be backported to the assertItemsEqual method of 2.7 (and to unittest2).
Error output:
AssertionError: Element counts were not equal: First has 1, Second has 0: ('b', (2, 3)) First has 0, Second has 1: ('x', (2, 3))