[TIP] Unittest Changes

Pekka Laukkanen peke at iki.fi
Mon Jul 28 15:56:06 PDT 2008

2008/7/22 Andrew Bennetts <andrew-tip at puzzling.org>:
> Pekka Laukkanen wrote:
>> Nice that you like the idea. I've always wondered why
>> 'unittest.TestCase' has those assert methods when in JUnit they are in
>> separate class. 'unittest' is a pretty direct JUnit port (even
>> according to its docs) so I wonder why the design has been changed.
> JUnit used to provide assertions via a test case superclass too (called "Assert"
> I think?).  Presumably the unittest module was inspired by that version of
> JUnit.  So I don't think it's that unittest changed the design, it's that JUnit
> has changed.

The difference is that in unittest there is no superclass containing
asserts that could be used without TestCase. Having a superclass with
only static methods wouldn't be to pythonic, though, and thus I
propose having a module with asserts as functions.

> Personally, I'm satisfied with the status quo (providing assertion methods via
> TestCases).  It's pretty common to implement custom assertion methods, and the
> natural home for these is usually on a TestCase subclass that I already have
> anyway.  It would feel a little weird to have a mix of "asserts.equals(...)" and
> e.g.  "self.assertAncestryEqual(...)", rather than consistently using "self."
> for all asserts.

If the old API is not changed (I don't propose that) you can keep
using this approach. Alternatively you can create your own asserts
module and have all asserts there (even standard asserts if you do
'from asserts import *' in the beginning of that module). Personally
I'd prefer separating asserts from other logic but that's mainly
matter of taste.

> Also, IIRC assertion methods in unittest.TestCase raise self.failureException
> rather than a hard-coded exception.  This is a bit of a minor feature, but it
> wouldn't be possible if the assertions weren't methods.

Even though this is a minor feature, I've actually used it at least
once when I implemented something on top of unittest. Having global
FAILURE_EXCEPTION in asserts module would make changing the exception
nearly as easy (import asserts; asserts.FAILURE_EXCEPTION =
MyCustomExceptio), but would have more side-effects. This probably
wouldn't be too big problem especially when the old mechanism would
still be there.

> Perhaps it might make sense to expose the standard unittest.TestCase assertion
> methods as staticmethods or classmethods?  Apparently JUnit does this.

I would found using 'unittest.TestCase.assertEqual' somewhat
cumbersome compared to 'asserts.assert_equal'. Additionally, you
couldn't import only some of those static methods similarly as you can
import only certain functions from a module. At least I also totally
agree with http://dirtsimple.org/2004/12/python-is-not-java.html that
"the idiomatic translation of a Java static method is usually a
module-level function, not a classmethod or staticmethod."


More information about the testing-in-python mailing list