This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: additional unittest type equality methods
Type: enhancement Stage:
Components: Library (Lib) Versions: Python 3.1
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: gregory.p.smith Nosy List: benjamin.peterson, ezio.melotti, giampaolo.rodola, gpolo, gregory.p.smith, michael.foord, ncoghlan, pitrou, pupeno, rhettinger, skip.montanaro
Priority: normal Keywords: patch

Created on 2008-04-08 01:01 by benjamin.peterson, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
unittest-new-asserts.diff michael.foord, 2009-03-30 21:11
unittest-new-asserts-gps04.diff.txt gregory.p.smith, 2009-03-31 07:50
unittest-assertis.diff michael.foord, 2009-04-04 17:27
unittest-sameelements.diff michael.foord, 2009-04-04 18:18
Messages (68)
msg65132 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2008-04-08 01:01
unittest has many redundant APIs (eg. failIf and assertFalse) which can
be phased out in 3.x. We may also want to change the actually methods so
they really do what they say:

if x == y:
   pass
 else:
   raise AssertionError(...)

rather than

 if x != y:
   raise AssertionError(...)
msg65142 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008-04-08 04:42
My plan:
- add deprecations to 3.1
- remove in 3.3
msg65145 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2008-04-08 05:20
In a separate bug report, Steve Purcell indicated that he was taking 
the module in the opposite direction and adding more redundancy in an 
effort to fully match the J-Unit API.
msg65146 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008-04-08 05:23
I'm all for adding new APIs that provide new functionality (we have a
few at Google that we really should contribute).

I'm not for having several aliases for the same functionality; it maybe
the JUnit way but Python's unittest.py is not JUnit not does it strive
for 100% JUnit compatibility -- the languages just are to different.

What's the bug# for Steve's proposal?
msg65148 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2008-04-08 05:43
See http://bugs.python.org/issue2249 for discussion.

Personally, I prefer minimalism and would like the API thinned 
considerably.  Also, I don't think all of the classes should be 
exposed.  AFAICT, nobody cares about test suite objects, test result 
objects, and test loader objects.  These are really artifiacts of an 
implementation originally designed to demonstrate how a unittest suite 
could be implemented.   

In Kent Beck's book on Test Driven Development, he complains that most 
unittest implementations spawned from his original work have grown far 
too complicated and would be better served by sticking to a simple 
framework for writing and running tests.

Some of that may have been lost in a effort to model J-Unit or to 
expose all the parts in support of people who want to use subclassing 
to write their own unittest variants and extensions (I have seen this 
in practice but it is somewhat rare). 

If making big changes to the unittest API is on the table, it is worth 
considering alternatives like py.test which is more powerful, easier to 
learn, much less verbose, and more in line with the way python is 
usually written.
msg65150 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008-04-08 05:54
Agreed that the various loader classes etc. are mostly a waste.  The sad
thing is that everyone who is serious about unittests has to reinvent
the code that finds files ending in _test.py on the filesystem, or
something like that, since that's *not* supported directly.
msg65154 - (view) Author: Steve Purcell (purcell) (Python triager) Date: 2008-04-08 08:01
Hey, I'm open to anything.  If I started writing unittest from scratch 
knowing what I know now, I'd probably have kept the API a little 
slimmer.  Oh, and I'd have named everthing according to Python 
conventions; my deepest and belated apologies for that.

I think the design has held up pretty well, even if it's arguably not 
the most pythonic.  Its familiarity to users of other xUnit frameworks 
really does help new Pythoneers start writing tests immediately.  And as 
for the TestLoader stuff, it looks (and perhaps is) a bit overblown, but 
I can't count the number of times people have asked me how to do obscure 
or unusual things with the module and I've been able to respond with 
something like, "just write a custom TestLoader/TestRunner".

I don't intend to take unittest in any particular direction; truth be 
told, I'm now only an occasional visitor to the land of Python, and I 
don't think I've had commit rights since the move to subversion.  My 
continued involvement with the unittest tickets is mainly to help 
provide input along the lines of "we discussed this years ago, and 
decided against it / thought it would be great".  Far be it from me to 
stand in the way of progress -- I'd be happy to see unittest re-worked 
in any way that makes sense.
msg65240 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008-04-09 16:42
>  Steve Purcell <purcell@users.sourceforge.net> added the comment:
>  Hey, I'm open to anything.  If I started writing unittest from scratch
>  knowing what I know now, I'd probably have kept the API a little
>  slimmer.  Oh, and I'd have named everthing according to Python
>  conventions; my deepest and belated apologies for that.

I think the current consensus is to start trimming the API in 3.1. We
could start documenting best practices in 2.6 and 3.0 though.

>  I think the design has held up pretty well, even if it's arguably not
>  the most pythonic.  Its familiarity to users of other xUnit frameworks
>  really does help new Pythoneers start writing tests immediately.

Though I wonder how common that use case is. Not all new Pythoneers
come from Java, you know... Many come from Perl, PHP, even C++, and
more and more come from not programming at all before.

>  And as
>  for the TestLoader stuff, it looks (and perhaps is) a bit overblown, but
>  I can't count the number of times people have asked me how to do obscure
>  or unusual things with the module and I've been able to respond with
>  something like, "just write a custom TestLoader/TestRunner".

I hope we can add more custom TestLoader/TestRunner subclasses for
some of the *common* use cases.

>  I don't intend to take unittest in any particular direction; truth be
>  told, I'm now only an occasional visitor to the land of Python, and I
>  don't think I've had commit rights since the move to subversion.  My
>  continued involvement with the unittest tickets is mainly to help
>  provide input along the lines of "we discussed this years ago, and
>  decided against it / thought it would be great".  Far be it from me to
>  stand in the way of progress -- I'd be happy to see unittest re-worked
>  in any way that makes sense.

And thanks for your continued involvement! I think the clue the
developer community can take from this is not to worry too much about
changing the original design; you don't seem to have a strong sense of
"ownership", which (in this case) sounds good to me.
msg65244 - (view) Author: Steve Purcell (purcell) (Python triager) Date: 2008-04-09 17:29
Hey, I came to Python from Perl, Java *and* C++!  I'm pretty sure the 
xUnits in all those other languages hold to the same basic API.

Adding more TestLoaders/TestRunners sounds like an excellent move.  I'd 
expect that once those common conveniences have been provided for, the 
core TestSuite/TestCase scheme will continue to be helpful.

I could certainly envisage the provision of convenience decorators that 
would remove some of the typical subclassing boilerplate  by 
transforming plain functions into TestCases.

I was recently sent a fun paper describing a mechanism for transforming 
doctests into 'unittest' tests, so there's obviously a lot of scope for 
fun additions and changes.

I'll be interested to see what people come up with, and to help a little 
if and when I can.
msg70982 - (view) Author: J. Pablo Fernández (pupeno) Date: 2008-08-10 12:52
Is there anything that can be done now about this issue? like renaming
the API and leaving the old names as aliases? If so, let me know and
I'll try to work on it.
msg80748 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-01-29 07:48
FYI - As a side note to this issue of removing the clutter of alternate
names - I intend to gather up the worthy non-clutter additional unittest
assertFoo APIs that we have at Google to contribute towards 3.1/2.7, my
goal is to do this before PyCon this year.

This thread from last spring summarizes the types of things I'd like
include already.

 http://mail.python.org/pipermail/python-dev/2008-April/078716.html
msg80773 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2009-01-29 16:01
As an side-side-note, I find much more important to add some kind of
test discovery since it is being duplicated in several packages in Lib/
and will continue being duplicated.
msg80774 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2009-01-29 18:16
@gpsmith: Way to go!

@gpolo: Alas, test discovery is now a much harder problem because it
depends on using conventions for test naming.  Unless all existing
implementations use the same conventions, it's hard to see how to
replace them.  Please bring that up on python-ideas@python.org.
msg84342 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-03-28 23:02
Attaching a patch that adds Google's unittest.TestCase assertFooEqual()
extensions and automatically uses rich comparisons in assertEqual() with
nicely formatted failure messages for list, tuple, dict, set, frozenset.

The following are added by this patch:

+    def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
+    def assertListEqual(self, list1, list2, msg=None):
+    def assertTupleEqual(self, tuple1, tuple2, msg=None):
+    def assertSetEqual(self, set1, set2, msg=None):
+    def assertIn(self, a, b, msg=None):
+    def assertNotIn(self, a, b, msg=None):
+    def assertDictEqual(self, d1, d2, msg=None):
+    def assertDictContainsSubset(self, expected, actual, msg=None):
+    def assertSameElements(self, expected_seq, actual_seq, msg=None):
+    def assertMultiLineEqual(self, first, second, msg=None):
+    def assertLess(self, a, b, msg=None):
+    def assertLessEqual(self, a, b, msg=None):
+    def assertGreater(self, a, b, msg=None):
+    def assertGreaterEqual(self, a, b, msg=None):
+    def assertIsNone(self, obj, msg=None):
+    def assertIsNotNone(self, obj, msg='unexpectedly None'):
+    def assertRaisesWithRegexpMatch(self, expected_exception,
expected_regexp,


As I said in the dev summit, I'll get some stats on how often each of
these are used relative to others from a large code base which has had
access to them for some time as an indicator of what may or may not be
worth making standard.

I did not include assertCommandSucceeds or assertCommandFails as those
are more difficult to do the right thing for everyone on cross platform
and our internal implementations use some other messy and not
integration-worthy internal libraries at the moment.
msg84353 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-03-29 01:02
With all due respect, I find the presence of numerous type specific
functions (assertListEqual, etc.) awful. I don't understand why the type
isn't simply cased in the standard assertEqual function. I also don't
think adding so many assert methods makes the API easy to remember and
pleasant to use.
msg84359 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-03-29 01:46
Some statistics from our large code base as to which of the assert
methods get used relative to the others:

These percentages are relative to the count of assertEqual(s) uses being
100% and cover python code written by a crazy large number of engineers.

assertListEqual	        4.61%
assertNotEqual(s)	1.91%
assertDictEqual	        1.90%
assertIn	        1.75%
assertSameElements	1.08%
assertIsNone	        0.47%
assertGreater	        0.37%
assertMultiLineEqual	0.36%
assertNotIn	        0.36%
assertLess	        0.24%
assertRaisesWithRegexpMatch 0.23%
assertIsNotNone	        0.20%
assertSetEqual	        0.16%
assertGreaterEqual	0.11%
assertLessEqual	        0.09%
assertTupleEqual	0.04%
assertSequenceEqual	0.04%
assertDictContainsSubset 0.02%

assertSequenceEqual is used by the List and Tuple equal functions so its
stand alone use isn't that relevant.  DictContainsSubset does not appear
to be used much.


I -did- add casing for the type to the main assertEqual method so it may
make sense to make the new type specific methods private so that they're
not part of the public API (ie: I agree with pitrou that it seems
pointless).
msg84360 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-03-29 01:52
Oh for reference, i left these out but they may interest people for
completeness sake.

assert_     15%
assertTrue   9%
assertFalse  5%

We don't currently have the auto type checking in assertEqual in our
internal codebase, direct use of the type specific methods has been
encouraged in the past but that doesn't mean it is the right thing for
Python.
msg84379 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-03-29 12:00
> I -did- add casing for the type to the main assertEqual method so it may
> make sense to make the new type specific methods private so that they're
> not part of the public API (ie: I agree with pitrou that it seems
> pointless).

Well, that's my own aesthetical feeling. Others may disagree :)
But I think the public API should stay reasonably compact, so that unit
testing doesn't incur a lot of cognitive overhead.
msg84413 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2009-03-29 16:13
The naming pattern (assertListEqual, assertDictEqual, etc.) is pretty
easy to pick up so I don't think the addition of several new methods is
a big deal.  Making assertEqual() do the right thing all the time is
hard if there are subclasses that might override __eq__ or do other
tricks, so I am glad that Greg only put the simplest test possible in
assertEqual.  And I would still want to have a way to explicit *disable*
that in case I am comparing containers with millions of items.  New
assertions like assertSameElements, assertDictContainsSubset or
assertMultilineEqual are not things that can be guessed, and they *are*
useful.

The names are also trivial to understand when reading tests that someone
else wrote, so I am not so worried about the cognitive effort.  I would
rather start deprecating the fail* variants and use assertTrue in favor
of assert_, and settle the question of whether to prefer assertEqual vs.
assertEquals (the former, please).

Finally, a simple refactoring of the code might be helpful where the
preferred name for each function is actually the name used in the 'def'
for it, so that tracebacks involving such assertions show the preferred
names, and so that their definitions can be found by searching the code
for e.g. "def assertEqual".
msg84426 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2009-03-29 19:54
Personally, I would prefer it if unittest got rid of all the various
ways to spell "assert" and just let test cases use the assert statement.
I use nose for most of my stuff which supports/allows use of the assert
statement.  I think my test cases are better for it.

(crap, crap, crap. I was scrolling through the messages and my finger slid
off the button on my laptop.  I pressed it again without really looking.
I didn't realize the mouse was no longer over the scrollbar's thumb and,
too late, saw that I had clicked the Remove button of this message "msg84360".  
I hope I clicked the cancel button soon enough.  If not, can it be
"unremoved" programmatically?  I have the text of the message if need be.)
msg84427 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2009-03-29 19:55
Just in case it can't be retrieved, here is Greg's text from msg84360:

--------------------------------
Oh for reference, i left these out but they may interest people for
completeness sake.

assert_     15%
assertTrue   9%
assertFalse  5%

We don't currently have the auto type checking in assertEqual in our
internal codebase, direct use of the type specific methods has been
encouraged in the past but that doesn't mean it is the right thing for
Python.
-------------------------------------------

Again, my apologies.

Skip
msg84430 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2009-03-29 20:46
Skip: bugs.python.org/issueXXXX?@action=edit&@add@messages=MSGNUM

This "Remove" button... :)
msg84431 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2009-03-29 21:13
I would love to use the time machine to kill the 'fail' variants as well
as 'assert_'.  However they are in use and we don't want to break
people's tests.  Breaking tests is painful.  And there are a lots of
tests.  So we'll have to support them for a long, long time.  Maybe we
can stop documenting them in 3.1 (this would also require changing
things so that the 'def' lines all use the 'assert' variants).  Then
maybe we can start deprecating them in 3.2 and 3.3, and perhaps remove
them in 3.4.  I recommend we let 2.x alone, but 2to3 should fix all these.

(And don't worry, Skip, somebody already put that message back.  You can
click on the link to deleted items in the History section at the bottom
of the issue.)
msg84432 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2009-03-29 21:33
2009/3/29 Guido van Rossum <report@bugs.python.org>:
>
> Guido van Rossum <guido@python.org> added the comment:
>
> I would love to use the time machine to kill the 'fail' variants as well
> as 'assert_'.  However they are in use and we don't want to break
> people's tests.  Breaking tests is painful.  And there are a lots of
> tests.  So we'll have to support them for a long, long time.  Maybe we
> can stop documenting them in 3.1 (this would also require changing
> things so that the 'def' lines all use the 'assert' variants).  Then
> maybe we can start deprecating them in 3.2 and 3.3, and perhaps remove
> them in 3.4.  I recommend we let 2.x alone, but 2to3 should fix all these.

Yes, actually this would be a great secondary use of 2to3's
infrastructure, and I think it could be done quite correctly because
people usually don't have many custom methods named failUnlessEqual()
etc.

Besides, they're tests, so people would know if they're broken. :)
msg84619 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-03-30 19:11
Updated patch after sprinting on this with Michael Foord.

TODO:
 * update assertRaisesWithRegexpMatch to be a context manager.
 * documentation.

i'm working on the docs now.
msg84622 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-03-30 19:21
> Updated patch after sprinting on this with Michael Foord.
> 
> TODO:
>  * update assertRaisesWithRegexpMatch to be a context manager.

Wouldn't it be simpler to make assertRaises return the exception and let
the calling code match it as it feels like?

(or, at least, find a shorter name than assertRaisesWithRegexpMatch :-))
msg84625 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2009-03-30 19:47
> Antoine Pitrou <pitrou@free.fr> added the comment:
> Wouldn't it be simpler to make assertRaises return the exception and let
> the calling code match it as it feels like?

Hm, that sounds awfully familiar. I can't recall if there was ever a
good reason not to do this.

> (or, at least, find a shorter name than assertRaisesWithRegexpMatch :-))

assertRaisesRegex?
msg84627 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-03-30 19:51
> > Wouldn't it be simpler to make assertRaises return the exception and let
> > the calling code match it as it feels like?
> 
> Hm, that sounds awfully familiar. I can't recall if there was ever a
> good reason not to do this.

IIRC some people felt that having a function named "assertSomething"
return something other None wasn't "pure".
The other reason is that you couldn't get the raised exception in a very
practical way if used as a context manager.

> > (or, at least, find a shorter name than assertRaisesWithRegexpMatch :-))
> 
> assertRaisesRegex?

Sounds better!
msg84633 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-03-30 20:10
New patch with assertRaisesWithRegexMatch as a context manager.
msg84650 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-03-30 21:11
Updated patch with asserts in unittest changed to explicitly raising
self.failureException, hardcoded AssertionError in tests changed to
self.failureException and addition of assertRegexMatches.
msg84757 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-03-31 07:41
New patch uploaded.  Based on mfoord's 200903301411 version.  Adds
documentation.  Cleans up a few things and fixes names on a few things.

This patch has been put up for review in:

 http://codereview.appspot.com/32080
msg84759 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-03-31 07:50
fixed the unintentional extra edits in the docs in gps04.
msg84795 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2009-03-31 15:01
Hi Greg, I've mostly reviewed for style...

http://codereview.appspot.com/32080/diff/13/1006
File Doc/library/unittest.rst (right):

http://codereview.appspot.com/32080/diff/13/1006#newcode611
Line 611: assertTrue(expr[, msg])
Make assertTrue the first/preferred/recommended spelling.

http://codereview.appspot.com/32080/diff/13/1006#newcode623
Line 623: :const:`None`.  Note that using :meth:`failUnlessEqual`
improves upon
failUnlessEqal -> assertEqual

http://codereview.appspot.com/32080/diff/13/1006#newcode624
Line 624: doing the comparison as the first parameter to
:meth:`failUnless`: the
failUnless -> assertTrue

(This kind of change may have to be done throughout.)

http://codereview.appspot.com/32080/diff/13/1010
File Lib/test/test_unittest.py (right):

http://codereview.appspot.com/32080/diff/13/1010#newcode75
Line 75: self.fail("%s and %s do not hash equal" % (obj_1, obj_2))
maybe better %r and %r ?

http://codereview.appspot.com/32080/diff/13/1010#newcode84
Line 84: self.fail("%s and %s hash equal, but shouldn't" %
ditto?

http://codereview.appspot.com/32080/diff/13/1010#newcode2313
Line 2313: self.assertRaises(self.failureException, self.assertIn,
'elephant', animals)
lin too long

http://codereview.appspot.com/32080/diff/13/1010#newcode2317
Line 2317: self.assertRaises(self.failureException, self.assertNotIn,
'cow', animals)
linr too long

http://codereview.appspot.com/32080/diff/13/1007
File Lib/unittest.py (right):

http://codereview.appspot.com/32080/diff/13/1007#newcode257
Line 257: class AssertRaisesContext(object):
While you're at it, can you add a docstring?

http://codereview.appspot.com/32080/diff/13/1007#newcode332
Line 332: # Map types to custom assertEquals functions that will compare
assertEquals -> assertEqual

http://codereview.appspot.com/32080/diff/13/1007#newcode512
Line 512: # should use their type specific assertSpamEquals method to
compare
assertSpamEqual

http://codereview.appspot.com/32080/diff/13/1007#newcode521
Line 521: def _baseAssertEquals(self, first, second, msg=None):
Mind dropping the trailing 's'?

http://codereview.appspot.com/32080/diff/13/1007#newcode526
Line 526: def failUnlessEqual(self, first, second, msg=None):
We had talked about making the 'def' define the recommended name, e.g.
assertNotEqual, and using aliases to keep the other names.  Do you want
to do that at the same time as this change or in a separate one?

http://codereview.appspot.com/32080/diff/13/1007#newcode581
Line 581: def assertSequenceEquals(self, seq1, seq2, msg=None,
seq_type=None):
Drop the trailing 's' in the name?

http://codereview.appspot.com/32080
msg84829 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-03-31 16:37
Reviewers: fuzzyman, GvR,

http://codereview.appspot.com/32080/diff/13/1006
File Doc/library/unittest.rst (right):

http://codereview.appspot.com/32080/diff/13/1006#newcode611
Line 611: assertTrue(expr[, msg])
On 2009/03/31 15:01:06, GvR wrote:
> Make assertTrue the first/preferred/recommended spelling.

Done.

http://codereview.appspot.com/32080/diff/13/1006#newcode623
Line 623: :const:`None`.  Note that using :meth:`failUnlessEqual`
improves upon
On 2009/03/31 15:01:06, GvR wrote:
> failUnlessEqal -> assertEqual

Done.

http://codereview.appspot.com/32080/diff/13/1006#newcode624
Line 624: doing the comparison as the first parameter to
:meth:`failUnless`: the
On 2009/03/31 15:01:06, GvR wrote:
> failUnless -> assertTrue

> (This kind of change may have to be done throughout.)

Done.

http://codereview.appspot.com/32080/diff/13/1010
File Lib/test/test_unittest.py (right):

http://codereview.appspot.com/32080/diff/13/1010#newcode75
Line 75: self.fail("%s and %s do not hash equal" % (obj_1, obj_2))
On 2009/03/31 15:01:06, GvR wrote:
> maybe better %r and %r ?

Done.

http://codereview.appspot.com/32080/diff/13/1010#newcode84
Line 84: self.fail("%s and %s hash equal, but shouldn't" %
On 2009/03/31 15:01:06, GvR wrote:
> ditto?

Done.

http://codereview.appspot.com/32080/diff/13/1010#newcode2313
Line 2313: self.assertRaises(self.failureException, self.assertIn,
'elephant', animals)
On 2009/03/31 15:01:06, GvR wrote:
> lin too long

Done.

http://codereview.appspot.com/32080/diff/13/1010#newcode2317
Line 2317: self.assertRaises(self.failureException, self.assertNotIn,
'cow', animals)
On 2009/03/31 15:01:06, GvR wrote:
> linr too long

Done.

http://codereview.appspot.com/32080/diff/13/1007
File Lib/unittest.py (right):

http://codereview.appspot.com/32080/diff/13/1007#newcode257
Line 257: class AssertRaisesContext(object):
On 2009/03/31 15:01:06, GvR wrote:
> While you're at it, can you add a docstring?

Done.  We also decided that this should be private so I've added an _.

http://codereview.appspot.com/32080/diff/13/1007#newcode332
Line 332: # Map types to custom assertEquals functions that will compare
On 2009/03/31 15:01:06, GvR wrote:
> assertEquals -> assertEqual

Done.

http://codereview.appspot.com/32080/diff/13/1007#newcode512
Line 512: # should use their type specific assertSpamEquals method to
compare
On 2009/03/31 15:01:06, GvR wrote:
> assertSpamEqual

Done.

http://codereview.appspot.com/32080/diff/13/1007#newcode521
Line 521: def _baseAssertEquals(self, first, second, msg=None):
On 2009/03/31 15:01:06, GvR wrote:
> Mind dropping the trailing 's'?

Done.

http://codereview.appspot.com/32080/diff/13/1007#newcode526
Line 526: def failUnlessEqual(self, first, second, msg=None):
On 2009/03/31 15:01:06, GvR wrote:
> We had talked about making the 'def' define the recommended name, e.g.
> assertNotEqual, and using aliases to keep the other names.  Do you
want to do
> that at the same time as this change or in a separate one?

Yes I'm going to do that in the next revision immediately after this
one.

http://codereview.appspot.com/32080/diff/13/1007#newcode581
Line 581: def assertSequenceEquals(self, seq1, seq2, msg=None,
seq_type=None):
On 2009/03/31 15:01:06, GvR wrote:
> Drop the trailing 's' in the name?

Done.

Description:
http://bugs.python.org/issue2578 - additional unittest type specific
equality methods that print useful error messages and type introspection
within assertEqual to automatically use them when deemed appropriate.

Please review this at http://codereview.appspot.com/32080

Affected files:
   M     Doc/library/unittest.rst
   M     Lib/test/test_gc.py
   M     Lib/test/test_struct.py
   M     Lib/test/test_unittest.py
   M     Lib/unittest.py
msg84831 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2009-03-31 16:41
LG.

http://codereview.appspot.com/32080
msg84836 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-03-31 16:57
Comments applied.  committed to trunk in r70837.  Needs porting to
python 3.1.

Next changes TODO:
 * rename the method def's and add deprecation warnings to fail* variants.

In room discussion at pycon 2009 sprints consensus on Equal vs Equals
names is that existing Equals names will continue to exist but remain
undocumented.  Arguments can be made for both (and some others) and we'd
like to reduce clutter but not drive the world crazy with nitpicking
deprecations over a single 's'.
msg84838 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2009-03-31 16:59
I think we should rename the method defs ASAP but not start deprecating
the old names until 3.2.  Otherwise many people's tests will be very
noisy and that's just annoying.  Give them time to migrate voluntarily.
msg84861 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-03-31 19:06
def's of the methods changed to be the official assert* names in trunk
r70864.  unittests added to confirm that all known method names continue
to work.

Guido - If we fix 2to3 to fixup unittests that use the fail* method
names to use the assert* names would you be okay with adding the
deprecation warning in 3.1 or should it really wait for 3.2 with a
removal in 3.3?

I'm fine with leaving the deprecation out for 2.7.
msg84866 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-03-31 19:10
If the deprecation causes noise people can just turn off the deprecation
warning surely?

Especially as transforming a codebase really is as simple as a global
search and replace. Personally I'd prefer earlier deprecation.
msg84885 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-03-31 20:01
trunk r70878 has the code issue an actual PendingDeprecationWarning for
the fail* methods and documents them as deprecated.  If anyone has a
better idea of a better way to state those deprecations in the docs,
feel free to jump in here.

I was unaware of the PendingDeprecationWarning (ignored by default)
prior to this.  I think that is what Guido was suggesting.  The question
of if we can do an actual DeprecationWarning for 3.1 or not still stands.
msg84973 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2009-04-01 03:42
I absolutely do not want it to warn by default in 3.1. 
PendingDeprecationError is fine.
msg85047 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-04-01 16:43
sounds good.  This is done for 2.7.

I will make sure it gets merged into 3.1 properly before closing.
msg85107 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2009-04-01 23:00
Do you mind if I rename all the double underscore methods that Greg's
patch added to _ underscore matching the style of the rest of the module?
msg85111 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2009-04-01 23:08
Do I mind? I *insist*! I thought put a note about that in the code
review but I guess Greg missed it. Thanks for noticing.
msg85116 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2009-04-01 23:16
Done in r71004.
msg85199 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2009-04-02 12:36
Bikeshedding a bit - the 'assertGreaterEqual' and 'assertLessEqual'
method names grate on me a little. My brain has to do a double take in
order to correctly insert the implied 'Or'. This reaction is made worse
when these two methods are juxtaposed with all the other "assert*Equal"
methods like DictEqual, ListEqual, SetEqual etc.

Would it be possible to lengthen these specific names to the more
explicit "assertGreaterOrEqual" and "assertLessOrEqual"?

Some really nice additions to the test module here! :)
msg85221 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2009-04-02 16:40
> Nick Coghlan <ncoghlan@gmail.com> added the comment:
> Bikeshedding a bit - the 'assertGreaterEqual' and 'assertLessEqual'
> method names grate on me a little. My brain has to do a double take in
> order to correctly insert the implied 'Or'. This reaction is made worse
> when these two methods are juxtaposed with all the other "assert*Equal"
> methods like DictEqual, ListEqual, SetEqual etc.
>
> Would it be possible to lengthen these specific names to the more
> explicit "assertGreaterOrEqual" and "assertLessOrEqual"?

No, please. Get used to it. Maybe it helps if you realize the parallel
with '__ge__'?
msg85242 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2009-04-02 19:02
Am I the only person who wishes all the assert* and fail* methods would
simply go away in favor of simply using the assert statement?

Skip
msg85243 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-04-02 19:07
Why do you need the assert methods to go away in order to use assert
statements?
msg85247 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2009-04-02 19:18
Michael> Why do you need the assert methods to go away in order to use
    Michael> assert statements?

You don't, but use of assert statements seems a hell of a lot more Pythonic
to me than all the assert* or fail* method names which I can never remember.

S
msg85249 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-04-02 19:22
> You don't, but use of assert statements seems a hell of a lot more Pythonic
> to me than all the assert* or fail* method names which I can never remember.

Two problems:
1. they are optimized away in "-Oxxx" mode
2. they don't provide good reporting in case of failure
msg85269 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2009-04-02 21:27
Thanks Guido - the __ge__/__le__ parallel does actually help me remember
the current names.
msg85274 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2009-04-02 22:49
>> You don't, but use of assert statements seems a hell of a lot more
    >> Pythonic to me than all the assert* or fail* method names which I can
    >> never remember.

    Antoine> 1. they are optimized away in "-Oxxx" mode

As far as I can tell for Python itself we never use -O while running unit
tests. 

    Antoine> 2. they don't provide good reporting in case of failure

I've never had a problem with that.  It yields a perfectly useful traceback,
and in the case of the nose package at least, it does the right thing with
it.

In any case, your test machinery will have to catch AssertionError
exceptions anyway.
msg85275 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-04-02 22:53
No - you catch self.failureException rather than AssertionError directly.

I use unittest precisely because of the rich failure information from
the assert methods - particularly the new ones in this patch!
msg85317 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-04-03 19:15
Why is assertMultiLineEqual not the default assert method for basestring?

Even for small strings the output is useful.
msg85326 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-04-03 20:28
assertMultiLineEqual might be reasonable as a default assertEqual for 
unicode.  I wouldn't want to do it for bytes (py 2.x string).
msg85327 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-04-03 20:29
Fair point. :-)
msg85399 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-04-04 15:06
I'd like to add assertIs and assertNotIs.

We have these at work and I would find them useful whilst writing tests
for another set of changes to unittest I'm currently working on!
msg85400 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-04-04 15:10
Le samedi 04 avril 2009 à 15:06 +0000, Michael Foord a écrit :
> Michael Foord <michael@voidspace.org.uk> added the comment:
> 
> I'd like to add assertIs and assertNotIs.

Let's call it AssertIsNot (we type "x is not None", not "x not is
None").
msg85401 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-04-04 15:12
I would *mmuch* prefer assertIsNot but it is not symmetrical with the
other asserts.
msg85405 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-04-04 16:40
> I would *mmuch* prefer assertIsNot but it is not symmetrical with the
> other asserts.

Well, apparently assertIsNotNone() has been added, so it would be good
to be symmetrical with that :)
msg85406 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2009-04-04 16:40
I found while merging this to Py3k that dicts can't be used in
assertSameElements because they are unorderable in py3k.
msg85416 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-04-04 17:27
Patch with assertIs and assertIsNot. Docs but nothing in NEWS as already
covered.

Ok to apply?
msg85422 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-04-04 18:18
Patch for Py3k with fallback for comparing unsortable sequences in
assertSameElements.

Removed the expected failure and added another test case to confirm that
this patch works for unsortable sequences that are the same (no fail)
and different (fail).
msg85431 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-04-04 20:50
Seeing how a change in assertNotEqual unveiled a bug in OrderedDict,
would it be desireable for each of assertEqual and assertNotEqual to
test both the '!=' and '==' operators?
msg85442 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2009-04-04 22:47
No, because the rich comparison docs explicitly state that the
interpreter makes no assumptions about the relationship between != and
== (or, more precisely, __eq__ and __ne__).

"""There are no implied relationships among the comparison operators.
The truth of x==y does not imply that x!=y is false. """

(from http://docs.python.org/reference/datamodel.html#basic-customization)

If someone is writing unit tests for comparison methods they should
explicitly test all 6 operations.
msg85556 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2009-04-05 19:05
fyi - Your docs in unittest-assertis.diff mention the wrong method name
(assertIsNotNone instead of assertIsNot).  fix that and commit.

The unittest-sameelements.diff patch looks good.
msg85560 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-04-05 19:22
Committed in revision 71263. Closing as there is nothing outstanding on
this issue.
History
Date User Action Args
2022-04-11 14:56:33adminsetgithub: 46830
2011-03-16 03:42:27ezio.melottisetnosy: + ezio.melotti
2009-04-05 19:23:30purcellsetnosy: - purcell
2009-04-05 19:22:41michael.foordsetstatus: open -> closed
resolution: accepted
messages: + msg85560
2009-04-05 19:05:35gregory.p.smithsetmessages: + msg85556
2009-04-05 18:25:06gvanrossumsetnosy: - gvanrossum
2009-04-04 22:47:57ncoghlansetmessages: + msg85442
2009-04-04 20:50:51pitrousetmessages: + msg85431
2009-04-04 18:18:22michael.foordsetfiles: + unittest-sameelements.diff

messages: + msg85422
2009-04-04 17:27:17michael.foordsetfiles: + unittest-assertis.diff

messages: + msg85416
2009-04-04 16:40:59benjamin.petersonsetmessages: + msg85406
2009-04-04 16:40:54pitrousetmessages: + msg85405
2009-04-04 15:12:16michael.foordsetmessages: + msg85401
2009-04-04 15:10:40pitrousetmessages: + msg85400
2009-04-04 15:06:21michael.foordsetmessages: + msg85399
2009-04-03 20:29:08michael.foordsetmessages: + msg85327
2009-04-03 20:28:20gregory.p.smithsetmessages: + msg85326
2009-04-03 19:15:49michael.foordsetmessages: + msg85317
2009-04-02 22:53:46michael.foordsetmessages: + msg85275
2009-04-02 22:49:44skip.montanarosetmessages: + msg85274
2009-04-02 21:27:04ncoghlansetmessages: + msg85269
2009-04-02 19:22:44pitrousetmessages: + msg85249
2009-04-02 19:18:44skip.montanarosetmessages: + msg85247
2009-04-02 19:07:27michael.foordsetmessages: + msg85243
2009-04-02 19:02:19skip.montanarosetmessages: + msg85242
2009-04-02 16:40:00gvanrossumsetmessages: + msg85221
2009-04-02 12:36:41ncoghlansetnosy: + ncoghlan
messages: + msg85199
2009-04-01 23:16:37benjamin.petersonsetmessages: + msg85116
2009-04-01 23:08:46gvanrossumsetmessages: + msg85111
2009-04-01 23:00:30benjamin.petersonsetmessages: + msg85107
2009-04-01 16:43:01gregory.p.smithsetmessages: + msg85047
versions: - Python 2.7
2009-04-01 03:42:13gvanrossumsetmessages: + msg84973
2009-03-31 20:01:27gregory.p.smithsetmessages: + msg84885
2009-03-31 19:10:18michael.foordsetmessages: + msg84866
2009-03-31 19:06:10gregory.p.smithsetmessages: + msg84861
2009-03-31 16:59:30gvanrossumsetmessages: + msg84838
2009-03-31 16:57:27gregory.p.smithsetmessages: + msg84836
2009-03-31 16:41:36gvanrossumsetmessages: + msg84831
2009-03-31 16:37:05gregory.p.smithsetmessages: + msg84829
2009-03-31 15:01:09gvanrossumsetmessages: + msg84795
title: Figure out what to do with unittest's redundant APIs -> additional unittest type equality methods
2009-03-31 07:50:31gregory.p.smithsetfiles: - unittest-new-asserts-gps03.diff.txt
2009-03-31 07:50:25gregory.p.smithsetfiles: - unittest-new-asserts.diff
2009-03-31 07:50:19gregory.p.smithsetfiles: - unittest-new-asserts-gps02.diff.txt
2009-03-31 07:50:05gregory.p.smithsetfiles: + unittest-new-asserts-gps04.diff.txt

messages: + msg84759
2009-03-31 07:41:38gregory.p.smithsetfiles: + unittest-new-asserts-gps03.diff.txt

messages: + msg84757
2009-03-30 21:11:55michael.foordsetfiles: + unittest-new-asserts.diff

messages: + msg84650
2009-03-30 20:11:01michael.foordsetfiles: + unittest-new-asserts.diff

nosy: + michael.foord
messages: + msg84633

keywords: + patch
2009-03-30 19:51:49pitrousetmessages: + msg84627
2009-03-30 19:47:33gvanrossumsetmessages: + msg84625
2009-03-30 19:21:57pitrousetmessages: + msg84622
2009-03-30 19:11:46gregory.p.smithsetfiles: - unittest-new-asserts-gps01.diff.txt
2009-03-30 19:11:29gregory.p.smithsetfiles: + unittest-new-asserts-gps02.diff.txt

messages: + msg84619
2009-03-29 21:33:17benjamin.petersonsetmessages: + msg84432
2009-03-29 21:13:56gvanrossumsetmessages: + msg84431
2009-03-29 20:46:06gpolosetmessages: + msg84430
2009-03-29 20:45:06gpolosetmessages: + msg84360
2009-03-29 19:55:31skip.montanarosetmessages: + msg84427
2009-03-29 19:54:17skip.montanarosetnosy: + skip.montanaro
messages: + msg84426
2009-03-29 19:49:56skip.montanarosetmessages: - msg84360
2009-03-29 16:13:54gvanrossumsetmessages: + msg84413
2009-03-29 12:00:10pitrousetmessages: + msg84379
2009-03-29 01:52:01gregory.p.smithsetmessages: + msg84360
2009-03-29 01:46:51gregory.p.smithsetmessages: + msg84359
2009-03-29 01:02:24pitrousetnosy: + pitrou
messages: + msg84353
2009-03-28 23:03:06gregory.p.smithsetfiles: + unittest-new-asserts-gps01.diff.txt

messages: + msg84342
2009-02-04 03:13:44giampaolo.rodolasetnosy: + giampaolo.rodola
2009-01-29 18:16:10gvanrossumsetmessages: + msg80774
2009-01-29 16:01:23gpolosetnosy: + gpolo
messages: + msg80773
2009-01-29 07:56:28gregory.p.smithsetpriority: normal
versions: + Python 3.1, Python 2.7, - Python 3.0
2009-01-29 07:56:12gregory.p.smithsetassignee: purcell -> gregory.p.smith
2009-01-29 07:48:33gregory.p.smithsetnosy: + gregory.p.smith
messages: + msg80748
2008-08-10 12:52:39pupenosetnosy: + pupeno
messages: + msg70982
2008-04-09 17:29:48purcellsetmessages: + msg65244
2008-04-09 16:42:21gvanrossumsetmessages: + msg65240
2008-04-08 08:01:33purcellsetmessages: + msg65154
2008-04-08 05:54:44gvanrossumsetmessages: + msg65150
2008-04-08 05:43:59rhettingersetmessages: + msg65148
2008-04-08 05:23:18gvanrossumsetmessages: + msg65146
2008-04-08 05:20:20rhettingersetassignee: purcell
messages: + msg65145
nosy: + rhettinger, purcell
2008-04-08 04:42:56gvanrossumsetnosy: + gvanrossum
messages: + msg65142
2008-04-08 01:01:25benjamin.petersoncreate