[Python-Dev] Cleaning-up the new unittest API

Raymond Hettinger raymond.hettinger at gmail.com
Sat Oct 30 07:56:38 CEST 2010


On Oct 29, 2010, at 9:11 PM, Michael Foord wrote:
>> Just to clarify. The following fails in Python 3:
>> 
>>     sorted([3, 1, 2, None])
>> 
>> If you want to compare that two iterables containing heterogeneous types have the same members then it is tricky to implement correctly and assertItemsEqual does it for you.
>> 
>> I agree that the name is not ideal and would be happy to change the name (deprecating the old name as it was released in 2.7). API churn is as bad as API bloat, but at least changing the name is something only done once.
> 
> Sorry for the noise. Suggested alternative name:
> 
>     assertElementsEqual
> 
> The docs need updating to make it clear that the method isn't just a synonym for assertEqual(sorted(iter1), sorted(iter2)) and that it works with unorderable types. 

I looked at this again and think we should just remove assertItemsEqual() from Py3.2 and dedocument it in Py2.7.  It is listed as being new in 3.2 so nothing is lost.

A new name like assertElementsEqual is an improvement because it doesn't suggest something like assertEqual(d.items(), d.items()), but it falls short in describing its key features:

* the method doesn't care about order
* it does care about duplicates
* it don't need hashability
* it can handle sequences of non-comparable types

Also, I think the O(n**2) behavior is unexpected.  There is a O(n log n) fast-path but it has a bug and needs to be removed.  See issue 10242.

The sole benefit over the more explicit variants like assertEqual(set(a), set(b)) and assertEqual(sorted(a), sorted(b)) is that it handles a somewhat rare corner case where neither of those work (unordered comparison of non-compable types when you do care about duplicates).  That particular case doesn't come-up much and isn't suggested by either the current name or its proposed replacement.

FWIW, I checked-out some other unittest suites in other languages and did not find an equivalent.  That strongly suggests this is YAGNI and it shouldn't be added in Py3.2.    There needs to be more evidence of need before putting this in.  And if it goes in, it needs a really good name that tells what operations are hidden behind the abstraction.  When reading test assertion, it is vital that the reader understand exactly what is being tested.  It's an API fail if a reader guesses that assertElementsEqual(a,b) means list(a)==list(b); the test will pass unintentionally.

See: 
http://www.phpunit.de/manual/3.4/en/api.html
http://kentbeck.github.com/junit/javadoc/latest/


Raymond




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20101029/da4268ee/attachment.html>


More information about the Python-Dev mailing list