I often hear “I’m prototyping” as an excuse not to do TDD. In this context prototyping means “there will be no unit tests around this piece of code, ever”.
In my opinion prototyping does not mean avoiding writing tests at any price, but to
- Create a piece of code without tests and check whether it works or not. If it does not, make it functional and – here it gets tricky – delete/comment out the whole thing. After that recreate the certain functionality using TDD practices. This process is kind of laborious and can be used when the functionality being implemented cannot be decoupled from the system. This approach can be employed when the functionality being implemented depends on a third party product, where the communication protocol is unclear.
- Create an application totally outside the boundaries of the system. The prototype application can be created with no test cases at all. It is because the prototype is not part of production code; it doesn’t matter for example if the code is not in a good shape because it is not part of the system and there is little chance that it will be read or modified by anyone other than its creator. Since the application is decoupled from the system under development it should be fast to run and see whether it produces the correct output (in less than five minutes, for example). The idea behind such a prototype application is to be created as fast as possible (sometimes in order to decide whether a third party application should be used or not), so anything beyond the happy execution path can be omitted. When the prototype works perfectly, it can be either thrown away and rewritten in TDD, or refactored/tested thoroughly and inserted into the system (this is risky though; by thorough I mean really thorough with all kinds of exception handlings and so on). Remember, this is not TDD anymore.
Basically, prototyping can be used when the functionality under development depends on a third party application. In my opinion, there’s nothing to prototype when dealing with parsing input commands, validating things, calculating hashes etc. In those cases the word “prototyping” is just a cheap trick not to write unit tests.
Well, the following post is about some feedback I’ve recently received on my activity regarding our self-improvement group. I was really about to abandon the whole thing, but my friend Lajos Fülep’s kind words made me continue.
In the last two weeks our little self development group was busy with a brand new topic: namely legacy code (legacy code in the sense of: “code that is working suspiciously, and have no tests around it.”). Some time ago I’ve posted some really ugly code that is full of bugs and has no tests at all. As discussed there, two rounds should be taken: one for adding tests , another one for refactoring it (and fixing the numerous bugs the code contains).
The first round was a pair programming session. The task was to cover the code as much as possible, and spot the mistakes – spot but, don’t touch them (hint: there are at least four major bugs in there). This task can be implemented in an hour. After that, we choose a reference implementation for the second round.
The second round is done randori-based. It means that there is a single laptop along with a projector, while people keep rotating in front of the computer. Everyone is allowed to make a single change. A single change can be: extracting a method, extracting a class, renaming TWO methods, variables etc. Basically the “one change” rule can be adjusted as you wish. I was kind of afraid of this randori-session; I thought people would be afraid of being creative while all fellow group members are looking at them. However, it went really well; people kept saying “I want to stay, this was half a change only”. What is very important here is that anyone not in front of the computer can speak only after the next change to be made has been named by the person at the computer. This means that you cannot give tips what to be done next (only if it was requested explicitly), but can argue whether a change is needed or makes sense at all.
Here’s the feedback I’ve received (translated from Hungarian):
I found this session very useful. What I liked about it was the task itself. It was cool we had to refactor an ugly piece of code. On the other hand it was very useful to me to see how other people were working and thinking. Way to go 🙂
Code refactoring in progress :-).
Some weeks ago @marcellhegedus and myself were doing a major refactoring on our code base. It took us long days, and we finally managed to get the code into a good shape. We split functions, extracted new classes, renamed methods and variables, deleted unused code. Besides cleaning out the code, we even made some optimizations to it. That optimization involved changing some of the API calls, so we didn’t have to read the database every time for every single piece of data. We found out that the API could check it directly whether an external object has a certain parameter or not, without reading its actual value. It was a nice and elegant shortcut that made that component reasonably faster. Continue reading “Don’t trust third party products”