[Python-ideas] Refactor Assertions Out of unittest.TestCase

Daniel Watkins daniel at daniel-watkins.co.uk
Sat Nov 30 10:26:14 CET 2013


Hello all,

I would like to propose refactoring the assertions out of
unittest.TestCase. As code speaks louder than words, you can see my
initial work at https://github.com/OddBloke/cpython.

The aim of the refactor is:
(a) to reduce the amount of repeated code in the assertions,
(b) to provide a clearer framework for third-party assertions to follow,
and
(c) to make it easier to split gnarly assertions in to an
easier-to-digest form.

My proposed implementation (as seen in the code above) is to move each
assertion in to its own class. There will be a shared superclass (called
Assert currently; see [0]) implementing the template pattern (look at
__call__ on line 69), meaning that each assertion only has to concern
itself with its unique aspects: what makes it fail, and how that
specific failure should be presented.

To maintain the current TestCase interface (all of the tests pass in my
branch), the existing assert* methods instantiate the Assert sub-classes
on each call with a context that captures self.longMessage,
self.failureException, self.maxDiff, and self._diffThreshold from the
TestCase instance.

Other potential aims include eventually deprecating the assertion
methods, providing a framework for custom assertions to hook in to, and
providing assertion functions (a la nose.tools) with a default context
set.

This proposal would help address #18054[1] as the new assertions could
just be implemented as separate classes (and not included in the
TestCase.assert* API); people who wanted to use them could just
instantiate them themselves.

I’d love some feedback on this proposal (and the implementation thus
far).


Cheers,

Dan (Odd_Bloke)

[0] https://github.com/OddBloke/cpython/blob/master/Lib/unittest/assertions/__init__.py#L15

[1] http://bugs.python.org/issue18054


More information about the Python-ideas mailing list