[FRPythoneers] Doctest

Steve Purcell stephen_purcell at yahoo.com
Thu Jul 26 00:43:22 MDT 2001


Hi Sean (and other folk),

Sean Reifschneider wrote:
>    [snip]
>        self.failIf(mult(0, 100) != 100)
>    [snip]
> 
> Which is better than what I expected, I was expecting to have to do, in
> effect:
> 
>    res = mult(0, 100)
>    exRes = 100
>    self.failIf(res != exRes, 'Expected %s, got %s' % ( res, exRes ))
> 
> But, I still don't like that the test aborts when it runs into a failure
> (unless you make every test it's own suite?), and that you don't get the
> expected value as well as what was actually produced.  Both of which you
> get from doctest.


What *should* a test case do if it runs into a failure? It *has* to stop.

Usually each test case has a couple of things it has to check in order to
know if the case is correct. If all the checks succeed then the case has
been successfully tested. The example you give later in your mail is a test
case for multiplication; all of the checks must succeed if multiplication is
to be considered to work correctly.

Test cases that are logically independent should be placed in separate test
methods:

     def testDivision(self):
        d = DivisorClass()
        self.assertEqual(d(4,2), 2)
        self.assertEqual(d(9,9), 1)
        self.assertEqual(d(9,3), 3)
        self.assertEqual(d(10,-1), -10)

     def testMultiplication(self):
        m = MultiplierClass()
        self.assertEqual(m(4,2), 8)
        self.assertEqual(m(9,9), 81)
        self.assertEqual(m(9,3), 27)
        self.assertEqual(m(10,-1), -10)

If doctest runs into a problem and keeps going, you're likely to get very
confusing messages from later tests.


> I'd be ok with PyUnit if it had:
> 
>    failCmp(res, expect):
>       if res != expect:
>          raise Whatever, 'Expected "%s" got "%s"' % ( expect, res )


PyUnit has that already. Look at the TestCase methods 'assertEqual' and
'assertNotEqual' (or the aliases 'failIfEqual' and 'failUnlessEqual').


> and the "fail*" commands were augmented with "noncriticalfailure*" or
> something.  For example:
> 
>    m = MultiplierClass()
>    failIf(m == None, 'Failed class instantiation!')
>    noncriticalfailureCmp(m(1, 2), 2)
>    noncriticalfailureCmp(m(2, 2), 4)
>    noncriticalfailureCmp(m(3, 2), 6)
>    noncriticalfailureCmp(m(4, 2), 8)
> 
> Some failures certainly will cause other failures, but assuming that all
> failures are fatal doesn't seem right...


It's a test -- it either succeeds or fails. 'Kinda fails' doesn't really
add too much. :-)


> I'll have to put it on the back burner of patches I should make.  I'm
> copying the PyUnit author in case it inspires him though.  ;-)

Thanks for the suggestions!

Best wishes,

-Steve

--
Steve Purcell, Pythangelist
Get testing at http://pyunit.sourceforge.net/
Test your web apps with http://webunit.sourceforge.net/



More information about the FRPythoneers mailing list