It's been over a month now at Resolver Systems, and since I have to describe what's it like to work there to a lot of friends and relatives, I'll document here what it feels to work in an Extreme Programming, using Agile techniques (I promise, no more buzzwords!).

So, programming using the above methods (see, no buzzword) basically boils down to two or three things:

  • You work together, on the same machine, with a different person each day
  • You write two tests before you write the actual feature
  • You have daily, short, stand-up meetings

So, without further ado, here's my experiences and thoughts for each of the above:

Pair Programming

This is by far the biggest change in the day-to-day experience as a programmer. A usual stereotype presents programmers as sad, lonely geeks that pound a keyboard at huge speeds, illuminated by the monitor glow, oblivious to the outside world in a Nirvana-like state.

You can forget all about sad, lonely geeks in Resolver Systems (judge from the faces! BTW, this needs updating :)! The fact alone that you share a desk with another human being for most of the working hours brings back a much-needed social contact in programming. As an aside, at Resolver Systems each and every one of us has a huge desk with two monitors to call his own, so we don't feel homeless.

We don't pound the keyboard at insane speeds, because it turns out that the actual coding a programmer will do is very little compared to the actual thought and design (even more so in a succinct language like Python). (Cynics will observe that as every desk has a different keyboard, we can't easily touch type anyway.) The biggest part of a day's work will be spent discussing, arguing, drawing diagrams and general designing. This leads to better overall architecture and code quality, but also, perhaps more importantly, leads to happier and sharper developers that have enjoyed a good intellectual argument with another human being.

I could go on and on about the positives of pair programming, but it also has minor drawbacks. The biggest one for me is that you don't go into the "Zone" nearly as much as when you code alone. This is countered a bit by assigning "spiking hours" to developers, when they work alone on problems that the best solution isn't obvious, so they'll hack around alone to come up with something that works. They will later pair with someone to wrap the hacky code in tests and general scrutiny.

Test Driven Development

Test Driven Development, or TDD is all about writing test code that covers a defect or a new feature before writing the actual production code.

In Resolver Systems we have two kinds of tests: Functional Tests and Unit Tests. Functional testing will launch up the actual application, move the mouse, click on buttons, type on the keyboard and check that everything is behaving as expected. Unit testing will check that an actual class or function will produce the expected results when given a set of arguments.

While Functional Tests have clear rules about what you can or can't do, some of our Unit Tests will seem more Functional, but the essence is clear: Functional Tests test a feature from the user's point of view, Unit Tests test the code from a programmer's point of view.

So, back to the day-to-day experience, when we have a new feature to implement or defect to fix, we'll go and write the Functional Test first. This, by definition, has to fail, since the feature isn't there yet or the defect isn't fixed. It's important that we actually run the test and see it fail, to make sure we test for the right thing.

After that, we'll dive into the code, to see where the fix should go. This should be obvious enough that doesn't take a long time. If we aren't sure, then perhaps this is a good candidate for a spike. In the case of a big change or a cross-cutting feature, this might take even a whole day (perhaps more). If we have to change the way a function works, we'll go and change the unit test first, see it fail, then change the function. If we have to write a new function, we'll write a test for it first, see it fail, then implement it.

Of course, this isn't always straightforward, and sometimes we'll cheat, write the function, see that it works reasonably well, then comment it out, write the tests and un-comment it bit by bit. I'm not very experienced yet in the best practices of TDD, and as days pass I'm sure it'll be more clear on how to do it.

To be continued...

This has been a long one, so I'll cover meetings and other things in a next post.

March 23, 2008, 2:18 p.m. More (813 words) 0 comments Feed
Previous entry: Switching to Emacs!
Next entry: Presenting truly international dates in Django

This post is older than 30 days and comments have been turned off.