Unit Testing: a couple of questions

Marco Bizzarri marco.bizzarri at gmail.com
Tue Oct 28 19:41:20 CET 2008

On Tue, Oct 28, 2008 at 3:56 PM, Emanuele D'Arrigo <manu3d at gmail.com> wrote:
> Hi everybody,
> I'm just having a go with Unit Testing for the first time and my
> feeling about it in short is: Neat!
> I'm a bit worried about the time it's taking me to develop the tests
> but after only a day or so I'm already much faster than when I started
> with it and the code is already much improved in terms of robustness.
> A couple of "philosophical" questions have emerged in the process.
> 1) Granularity
> Given a simple class
> class myClass():
>    def __init__(self, data):
>        __data = data;
>    def getData(self):
>        return __data
>    def setData(self, data):
>         __data = data
> I've been wondering: where do I stop in terms of testing for things
> that could go wrong? In this case for example, it might be reasonable
> to expand the class to make sure it only receives integers and test
> accordingly, i.e.:
>    def setData(self, data):
>        try:
>             data = int(data)
>        except ValueError:
>            raise ValueError("Argument received cannot be converted to
> integer: " + data)
> But would it be reasonable to test also for the assignment operators?
> After all, if, for some strange reason, there isn't enough memory,
> couldn't even __data = data potentially fail?
> 2) Testing in isolation
> I'm not entirely clear on this point. I can see how I need to test
> each path of the program flow separately. But should a test -only-
> rely on the object being tested and mock ones in supporting roles?

IMHO, don't do that. Mocking everything and anything can become
incredibly complex. Wait to do it. As usual, experience plays a big
role on this; start mocking on what will make your test *simpler* and
easier to write and to understand, for you today and for you tomorrow
(and remember that you tomorrow is a different one from you today).

Before writing a mock, ask yourself: can I use a real object? The both
of you know the behaviour of the real object; you hadn't to think
about what some you yesterday wrote inside it.

> I.e. would this be wrong if SupportObject is not a mockup?
> def testObjectToBeTested _forReallyBadError(self):
>        supportObject = SupportObject()
>        objectToBeTested = ObjectToBeTested()
>        result =  objectToBeTested.addSupportObject(supportObject)
>        self.failIf(result != kSuccess, "Support Object could not be
> added!")

> I can see how if the SupportObject class had a bug introduced in it,
> this test would fail even though it has nothing to do with the
> ObjectToBeTested class.

> However, creating mock objects can be quite an
> overhead (?). I'm wondering if there is a threshold, even a fuzzy one,
> under which it isn't worth doing and a test like the one above is
> "good enough".

> What do you guys think?
> Manu
> --
> http://mail.python.org/mailman/listinfo/python-list

Creating mock objects in python can be quite easy; even more if you're
on a greenfield project, and not with some thousands or ten of
thousands of legacy code around. So, the burden is not that much. If
you end using more than a couple of mocks in one test, most probably
there is something wrong, and it would be better if you reconsider
your design.

Also, think if you really need mock object in your tests. Can't it be
easier to use a "real" object? Unless creating it is really complex,
and making it show the behaviour you want it to show is hard or
unclear, you can use it directly.

You wont' use a mock for a datetime object, am I right?

Moreover, don't fight your problem (integrating your objects) at the
wrong level (unit testing); you'll need integration tests, where you
use your *REAL* object end-to-end, maybe even talking with other
subsystems, in order to check that you are working for real. And
there,maybe, you could discover that your discipline failed and you
didn't changed the signature of the method of a mock object after you
changed it in the real one. It happens, so, put your tests in place to
catch this problem.


Marco Bizzarri

More information about the Python-list mailing list