Adding static typing to Python

Magnus Lyckå magnus at thinkware.se
Thu Feb 21 09:00:38 EST 2002


Hm... I thought I replied to this, but it's nowhere to be seen...

 > "Magnus Lyckå" <magnus at thinkware.se> wrote ...
 >> I'm trying to adopt the XP habit of writing tests first, and then only
 >> code enough to make the test pass. It's sometimes difficult. It
 >> requires some diciplin not to get carried away while writing the code,
 >> and do more than I've written tests for. When I do get carried away
 >> I end up having to write a whole bunch of boring tests
 >> afterwards, and that feels like a drag, because then the writing
 >> of tests is not part of the creative process. And it's difficult
 >> to be sure that I actually have all the tests I need then.

Steve Holden wrote:
 > As far as this goes, EITHER you aren't being sufficiently rigorous in
 > defining your tests, OR you are over-specifying unnecessarily during

Sorry for my bluntness, but are you referring to some theory you read
about, or is this what you personally practice? ;-) I didn't see any
complete unit test suites included in the zip supplementing your book. ;-)

 > implementation. This latter is a particularly troublesome waste of
 > programmer time, which XP attempts to eliminate with its well-known
 > (?) "You aren't gonna need it" credo:

No, that's not it. Why wouldn't I write a test for it if I felt that
it was a good function. Whether I need it now or not! If I think it's
a good thing, I would normally start by writing a test case. That's how
I define its interface! Functions you don't need now needs test cases
even more than other code or they will rot, but if you don't test them
and don't use them, they won't normally cause any other trouble than
being dead weight that you can do without.

I'm normally thorough in my unit tests. For me, writing these tests
have become a way to design interfaces, predict problems and create
examples for proper use of a class. Before, I usually wrote comments
before I wrote the actual code. Now I mainly write the tests instead,
and my customer complains about the lack of comments... :-(

No, the problem lies elsewhere.

As you know, it's possible to write code without writing tests first,
and when you are pressured to deliver, there is really a short term gain
in most cases to skip the tests. The problem is that it's both more
difficult and boring to write test afterwards, so in the long run you
will spend more time, and have less reliable tests. This is probably a
good enough reason to always ignore the short term gain, but sumetimes
you get pressured to deliver now! Maybe because you've been posting at
comp.lang.python when you ought to have been programming....

A particular problem I see is that I haven't found any good way to
unit test my GUI code (wxPython) automatically. I'm not going to try
tools like WinRunner or Rational Robot. They would cost too much in
money and time for my needs, and also be to slow to run as a part of
a normal unit test sequence. And there is no way you can write the
tests in advance of coding with points and click tools like that.

[Successful GUI unittesters, please stand up, and explain how you
do it.]

I am trying to keep the GUI layer as thin as possible, but I realize
that my opinion of what is thin enough changes as the project evolves.
As the code grows, I tend to refactor code from the GUI modules to
pure logic modules that are independent of the GUI. It might be such a
thing as how objects are sorted in a GUI listbox. Initially that seems
to be a pure presentation issue, but then new requirements arise and
there are logic functions that relate to the order. Then the ordering
has to take place in the logic layer. If the required features creep
on you slowly, you might have implemented a bit more in the GUI than
you ought to have... There is often a gray zone between the GUI layer
and the logic layer. Accepting such a thing and being able to refactor
it is one of the points with XP, but in reality it doesn't work so well
when you move funtions between systems/layers such as between GUI a
logic layer or between logic layer and database. These refactorings
can't really utilize the unit tests well.

All the logic modules use unit tests, but the GUI modules don't. So here
I basically get chunks of code, or at least well defined behaviour, that
I move from GUI to logic, and thus into the realm of unit tests. When
all is well, I solve this situation like this:

I see the function in the GUI code, and I think. "Hm, this logic should
be moved to that module, and I should access it via such and such
interface." I then code that interface in the unit tests, implement the
function in the logic module, and when all tests pass, I change my GUI
to use that interface and remove the logic from there. But there is a
problems.

Since the code is really already written, it's difficult (and wasteful)
to forget about the written code, and start all over from scratch. And I
don't have a selective clear memory switch in my brain, so I really can't.
This means, that however you turn it around, the unittests are a bit of
an afterthought, not the integral part of the creative process they should
be.

Even if I did have GUI unittests, I would probably have to rewrite them
a lot to make them call the logic layer directly. Sure I can test the
logic layer indirectly with the GUI tests, but a) It might be better to
test GUI against logic stubs most of the time so that the tests and
development of the GUI layer is less dependent of the current state of the
logic layer. b) Once the functions are in the logic layer I might want
to call them outside a GUI context. Maybe from a web framework. Then
I need to be able to test it without the GUI. The web interface might
use features the GUI doesn't use or vice versa.

To be honest, I feel that the whole XP unit test philosophy works well
when you can use it all the time, but as soon as you have to deal with
including already written code, without unittests, into your project,
you are in trouble. You might have to pay the price by throwing away
perfectly functional code due to lack of unit tests, or suffer the
consequences of living with poor unit tests.

I know, many people write test code after they have coded, and these
tests can be very useful, but they are not unit tests in the XP sense.

/Magnus




More information about the Python-list mailing list