Moving from cowboy coding to agile development

Monday, April 24, 2006

Abusing TDD genetically

I recently made a small program as an example of a genetic algorithm. It was a minor school assignment, so the algorithm type to use was set in advance. Trying to use TDD as much as I can nowadays, I once again started writing code tests first.

After learning about how tests should drive design earlier, I now faced another interesting situation. Part of the design (the algorithm type bit) was already set, so the tests should actually adapt to that. I thought about how I should write tests in a case like this, and decided to experiment a little. Instead of writing tests for existing code (that didn't actually exist yet, but was quite thoroughly planned and only waited to be written), I tried to come up with tests that could have forced me to choose the algorithm I had already thought about. I know this was not anything like the approach TDD is meant to motivate, but it was fun - and writing unit tests still really paid off.

I managed to write tests that drove me towards the algorithm I had already partly designed and made the original design, in a sense, justified. Writing really demanding tests also made me improve the original design by showing that some details in the algorithm worked only occasionally as I had meant them to work. "Occasionally" is an important thing here, since genetic algorithms form a partly random approach to finding solutions in large search spaces.

Next I will present some examples of how unit testing helped me while writing a simple genetic algorithm. If you're not familiar with the concept, you might want to quickly browse Wikipedia's article on the subject. If you want to skip that, let's just say the algorithm is all about evolution (of solutions to the problem) and leave it at that. :)

Uncle Bob's blog post Extract Class provided me with a good way to test randomness. For example, I implemented the mutation of individuals so that the likelihood of mutation depended on the fitness of the individual: a perfect individual should never mutate, a strong individual should mutate only with a small likelihood, and a very poor individual should almost always mutate. So, I wrote tests for each case, writing a loop in which I called the mutation control method and counting the number of times a mutation actually happened.


public void testStrongIndividualVeryUnlikelyMutates() {
Individual original = new Individual("88888");
Individual after;
int changeCount = 0;
for(int i=0; i<1000; i++) {
after = new Individual("88888");
after.mutateIfBadFitness();
if(!original.equals(after)) {
changeCount++;
}
}
assertTrue((changeCount < 250) && (changeCount > 50));
}



One of the things unit tests helped me improve was generating offspring for two parent individuals. Since I didn't want the individuals to produce exact copies of themselves (since that would not give me any new information), I wrote a test that ensured the offspring was different from both parents. I was surprised to see the test fail with randomly generated individuals, since I thought a good selection of the crossover point alone would solve this. I soon realised that if the parents had identical "DNAs" on one side of the crossover point (e.g. "123|456" and "888|456"), the offspring would be an exact copy of one the parents. This was really easy to solve by forcing the offspring to mutate at birth, but I might not have found the flaw without a good test.

All in all, the task was fun and educating, although my approach probably added a (big) twist of solid coding horror to TDD.

Wednesday, March 22, 2006

Doing What I Love

While doing some study-related research, I stumbled upon a nice article on doing what one loves by Paul Graham:
http://www.paulgraham.com/love.html

Although I might disagree with one or two particular things, I think Graham has some excellent points. Especially his musings on people's motivations sound really familiar and accurate. They reminded me of Terry Pratchett's words: "Too many people want to have written." Luckily the hacker culture probably isn't as tempting as writing novels, and "Too many people want to have written killer apps" isn't excruciatingly true. At least, not yet.

P.S. If someone has read Graham's book Hackers & Painters, let me know what you think about it.

Monday, March 20, 2006

My Agile Week

Last week was probably more agile for me than any other week has ever been. On Wednesday I participated in my third randori coding dojo, and on Friday I eagerly listened to each of the three presentations in the agile seminar at Kiasma.

The seminar was absolutely great. The first presentation was Vasco Duarte's Team Building and Agile Software Development, followed by Sebastian Nykopp's Test Automation in Agile Development Today and - last but definitely not least - Joseph Pelrine's How Agile Works: Complexity and Agility. Vasco Duarte and Joseph Pelrine talked more about the social and "soft" side of software development. Some of the stuff sounded pretty familiar to me because of my leadership and management studies, but there were also several new things and the familiar ones were now tied to my own trade better than ever before.

Sebastian Nykopp's presentation was more on the technical side, and thus perhaps a bit more challenging to listen to. However, having learned TDD so far only at grass-roots level, it was really nice to see the whole bundle of test automation from FitNesse to the (familiar) JUnit unit tests. As I wrote in my last post, I really should get a grip of TDD on a larger scale, so this presentation really hit a good spot.

I think the presentations gave me some valuable ideas on the ways I could try to get TDD (and perhaps some other XP methods, later) started at my workplace. We'll see.

The dojo on Wednesday was - again - loads of fun. This time the dojo was held at the FifthElement premises, being the first dojo outside of the Reaktor office I have participated in. Although I consider myself as a novice in TDD, I actually started feeling the agony of being on the red bar too long... We stayed "on the red" for over five minutes during some big change, and although (or because of) I wasn't at the keyboard at the time, I almost started feeling uneasy physically, waiting for the green bar to appear. :)

Joseph Pelrine said on Friday "[After RUP,] Agile was like a homecoming for me". I can't say I feel the same, but there's definitely something in the agile ways that I find more and more alluring. I'm already feeling TDD puritanism creeping in, and I really like the feeling.