[TIP] Interface vs Implementation Testing

Michał Kwiatkowski constant.beta at gmail.com
Mon Apr 16 12:28:55 PDT 2007


On 4/16/07, Raphael Marvie <raphael.marvie at lifl.fr> wrote:
> I have a queue of request providing the functions: add(request),
> delete(request), list(), next(), and destroy(). I am implementing
> using TDD, so tests are written before implementation. Then, would
> you favour tests to be interface-based or implementation-based?
>
> As a first implementation the queue persistency is to be managed
> using the file system (a folder for the queue, a file per request --
> containing the request details). But, another implementation may be
> chosen later on, so tests should be re-usable.
>
> Would you:
>
>   a. write interface-based tests and implementation specific ones
> (the first ones could then be re-used later on),
>
>   b. write interface-based tests only (but you cannot completely be
> sure your implementation works fine),

I'm gonna challenge your belief and say that with proper test cases
you *can* be sure your implementation works fine. Every one of your
tests should verify that your specific implementation adheres to some
specification. If you cover your specification with tests completely
you can with much confidence say that your implementation does the
right thing. If you're not sure that implementation works fine, you
should revise your tests.

Having said that, if your implementation is complicated enough, you
should have separate tests for parts of it. *But*, those tests will
check for other things that the first set of tests. It's just a matter
of modularizing your code. On the lower level you have functions which
operate on files, while on higher level you think about queues and
requests. Your tests should reflect those differences. To sum up, do
black-box testing of your interfaces, but on many levels, which
correspond to granularity of your code. Once you decide to replace one
part of implementation with another, depending on its level you will
have to replace dependant tests, while higher-level tests should be
left intact.

And remember that unless you want functional tests you should mock as
much as you can, checking only for specific parts of behaviour at
time. With mocks you can also simulate errors and special conditions,
what makes your test cases even more rich.

> ps for the moment, I would say a.1 in python and a.2 in Java.

Your testing method should not depend on a language, but on behaviour
you want from your program. What language it is written in is just a
detail. ;)

Cheers,
mk



More information about the testing-in-python mailing list