dynamic typing questions

Robert Brewer fumanchu at amor.org
Sat Dec 20 19:50:09 CET 2003

I wrote:
> > Zuh? Unit testing doesn't replace a good debugger; they 
> work together.
> > Unit testing can only show you THAT a test has failed--it can't show
> > you where, how, or why. Think of exception handling (and especially
> > tracebacks) as a mini-debugger.

Then Dennis Lee Bieber wrote:
>         Your "units" are too big then...
>         To my mind... At the, possibly extreme level, the 
> unit under test 
> should be small enough that testing proves you /can not/ cause a 
> failure in that unit -- any condition that can not be trapped and 
> corrected while inside that unit should raise/return a documented 
> exception/error code meant to be handled by the next level 
> up. With the 
> bottom "proved", any failures in the next level up in 
> integration have 
> to belong within the "unit" of that level and should not require any 
> changes to the "proven" sub-units.  

Baloney. Your own quotes betray you: "units", "proved", and the word
"extreme". Here's a sample I ran into recently (snippet of a much larger
ADO abstraction module):

import datetime
import win32com.client
import pywintypes
from win32com.client import gencache
gencache.EnsureModule('{EF53050B-882E-4776-B643-EDA472E8E3F2}', 0, 2, 7)
def cast_date(self, dbfield):
    if dbfield.Value is None:
        return None
    if dbfield.Type == win32com.client.adDate:
        return datetime.date.fromordinal(dbfield.Value)
        # It's a string, not a Date.
        return datefromstring(dbfield.Value)

The cast_date "unit" was not producing errors--the entire MVC
application would simply stop running; its process would disappear. So
please, devise unit tests to isolate this without using a step-through
debugger. What, are you going to write a unit test for each line of
code? As it happens, the failure occurred upon calling dbfield.Value
when it was a date value before the epoch. (IIRC I was originally
converting it to a float, before the datetime module came along). The
point is, you can't always trap errors. I needed to know exactly which
line of code, which call, was crashing the app. So not only did I need a
stepping debugger to isolate which statement in cast_date was failing, I
had to use a debugger to find out which line of code in the unit test
was calling the failing code!

Unit tests are wonderful, _IF_ you pre-conceive all the corner cases.
This is, of course, impossible in any sufficiently powerful system to be
worthwhile. Unit test are the greatest thing since sliced bread. No
argument from me. But Mr. Roth's hyperbole regarding the usefulness of
debuggers is out of place. IF you only use code you write, and IF you
fully understand your problem domain and range, then you MIGHT not need
a debugger. The rest of us mortals use them when they're needed.

Robert Brewer
Amor Ministries
fumanchu at amor.org

More information about the Python-list mailing list