[TIP] new assertion library for unit tests

Michael Gratton michael at quuxo.com
Tue Aug 12 22:50:43 PDT 2008

On Wed, 2008-08-13 at 14:05 +1000, Andrew Bennetts wrote:
> Can you give an example of a test written in both styles where you feel Achoo is
> a big improvement?

Sure. I guess I should start by indicating where I think unittest's
assertion methods fall down, namely they don't provide a rich enough set
of assertions and that they don't generate useful error messages.

> For instance, <http://web.quuxo.com/products/achoo/doc/> has this example
> test method:
>     def testSplit(self):
>         s = 'foo,bar'
>         calling(s.split).passing(',').returns()\ 
>             .length(2)\ 
>             .index(0).equal_to('foo')\ 
>             .index(1).equal_to('bar')
> The obvious equivalent without Achoo seems much simpler and clearer to me:
>     def testSplit(self):
>         s = 'foo,bar'
>         self.assertEqual(['foo', 'bar'], s.split(','))

To hand-waive for a moment the examples in the docs were contrived to
give some idea of how to use the API, rather than illustrating what
makes a good tests - although this would be a good thing to do anyway,
I'll need to find better examples.

Anyway, I still prefer Achoo's approach here, because even though in
this case it is more verbose, it is making a lot of otherwise implicit
assertions explicit and because it attempts to providing useful error
messages by default. To achieve the same result using unittest's
methods, you would need to use multiple assertEquals calls and specify
an error message for the length. I believe the real equivalent would
look something like:

  def testSplit(self):
      s = 'foo,bar'
      expected = ['foo', 'bar']
      actual = s.split(',')
      self.assertEqual(len(expected), len(actual),
                       'Length of %s expected to equal %s' %
                       (expected, len(actual)))
      self.assertEqual(expected[0], actual[0])
      self.assertEqual(expected[1], actual[1])

For a small list like this it might not bee a problem, but when testing
more complex objects or multiple properties/behaviours of an object at
once, I think Achoo wins out.

> Another example test method doesn't look like it would work:
>     def testLength(self):
>         s = 'foo'
>         requiring(s.length).equal_to(3)
> Surely “s.length” will raise an AttributeError in that example?

Yes, I need to lay off the crack pipe a bit. Thanks for pointing that
out, I'll fix it on trunk and hopefully come up with some better
examples, too.


Michael Gratton <michael at quuxo.com>     
Quuxo Software <http://web.quuxo.com/>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://lists.idyll.org/pipermail/testing-in-python/attachments/20080813/7a30097a/attachment.pgp 

More information about the testing-in-python mailing list