CAIR Story 2: A day of test driven development, my style.
Its been a long while since I blogged, partly because I am up to neck with work and partly because I don’t have access to a computer outside of my job. For someone who’s been addicted to computers, spending more time without one is highly frustrating, so frustrating that I have actually taken to reading books (the dead tree kind) on economics!
I’ve been doing more than my fair share of development these days, not that I am complaining, but just that I am having less time for other interesting stuff that I would like to do, like work on my pet projects or blog. And due to self-imposed constraints on quality, espescially with production code, test driven development is slowly becoming second nature to me. I still can’t wrap around my mind to writing tests first before sitting down to writing the actual code. I’ve tried that, but my normal linear sequential brain simply cannot handle it.
However, one thing that is a work around for people with lesser amount of gray cells, like me, is to co-develop your test routines along with the code. Thats what I’ve been doing these days and I can assure you that it saves you a lot of trouble. It surely has saved me tons of it. Unit testing has become a way of life with me, just that my tests are written “while” I write my code rather than before writing it (agile) or after (??) writing it.
Here is a little snippet from an experience that I would like to share. One of the hardest things to write is “proper” concurrent code. Multi-threaded kind is fun enough and it all resides on one computer and within the same address space, so sharing data is easy. Now, imagine the same scenario, but just that your threads might run on any of the many machines that are available in a cluster. Not only that, from the programmers point of view they should behave just like threads in a program, and sharing data should be just as easy.
One of the easiest ways of doing that is simply using a virtual machine (like the JVM or .NET), and let the virtual machine handle threading. Its not too difficult to let the VM take care of threads and handle the data requests. It can all be done with some form of message passing (infact, my first prototype actually passes ad-hoc message objects marshalled across a socket). The difficulty here arises because, unlike on a uniprocessor machine, here you get true parallelism. And, like with any good gift, you have one big disadvantage to take care of, debugging this code is scary. And when you have the whole infrastructure in place, there are so many components running in parallel that finding out what went wrong where, would be a job best left to sherlock holmes.
A manageble solution to that problem is unit-testing, and writing the tests along with writing the code has some advantages. One thing that runs in your mind when you are writing your tests, is “how would my code handle this test”. Infact more than half my time, I spent on working out (in my head) on how my code would handle the tests.
This process, imho, has the same advantage writing (pen/paper/ms-word style) has. It gives shape to your ideas. Infact, by the time I had finished writing some of my tests, I had a very good idea of the expected behaviour and the actual behaviour of my code. Some times, I caught errors, even before I tested the code. Infact, writing tests is actually a way of looking at your code from a completely different point of view. Also, when you are writing tests along with the code you are developing, you have your code so fresh in your mind that, its a lot easier to reason about it, rather than when you write it afterwards.
So, maybe, test-driven development has something to it after all.