I recently started a gig with a new client site. In the last 18 months, they have brought in a consultant to move to Extreme Programming (XP) and Test-Driven Development (TDD). Prior to this assignment, I liked some of the items on the TDD menu, but only those which seemed reasonable. I've since realized that "reasonable" equated to "known" and "comfortable".
Before (long before my arrival):
- They used the waterfall method. Every 6-8 months or so, people were asked for time-estimates on titanic swaths of functionality.
- People were sequestered away in the Dilbertian cubes, emerging on occasion for a weekly ponderous, nebulous meeting.
- The build took 4 hours!
- They had tests that blurred unit-testing and integration-testing. They were slow and difficult to write.
Now:
- Work is done in 2-week iterations. Though there is a large-scale sense of direction, work is estimated in much smaller units (i.e. what can be completed in this iteration?)
- There is a war-room: a large conference room that often has 8-10 people in it. Often times, the people are paired up. Iterations are planned in this room as well. It is extremely social and highly reminiscent of a "computer lab" from university.
- The build takes 10 minutes. There are a ton of unit-tests (via JUnit) and some integration tests.
- The team culture absolutely encourages that developers write tests first.
My main concerns going into this were:
Can I concentrate in a war-room?
Surprisingly: yes. It has to be noted that its inhabitants are pleasant, kind-hearted professionals, and that it is not a stressful "boiler room". It's a big lab. That said, the war-room has been fantastic, especially for newbies like me, as the company's domain is highly technical (medical devices). The main upside is that people can learn about the product and others' work, just from osmosis and yet still concentrate on their own work. It is also highly efficient: one can just call out "hey, is the build breaking for y'all?" or "does anyone remember where the XYZ config property is set?".
The war-room requires significant infrastructure. This group uses new-age Wise terminals (hello 1980s!) to remote-desktop back to someone's computer in the cube. For this to work, they have a standardized IDE environment. One must use Eclipse version 3.x.y. In this way, it doesn't matter whose machine is used as the workstation.
Another key thing is that people are
free to return to their cubes if they so desire. That is critical, and I certainly do that at times. Interestingly, I sometimes feel "lonely" after being in my cube for too long. Perhaps geeks are social after all?
A final thought: it is very hard for people to email/surf in a war-room. Peer-pressure is a powerful thing.
Can I really pair-up with someone?
Another surprise: yes. Again, I am lucky to be working with 2 people who are bright, articulate, and kind. This might not work if that weren't true, but for my situation, it has worked brilliantly. My main partner, Kevin, and I share roughly the same level of ability and experience, except that he has been on the project for 2+ years.
My first 2 weeks was spent as co-pilot, watching him work as he thought out-loud. This was infinitely more productive than sitting in a cube, alone, sifting through the code and checking the time to see if it was lunch-time yet. Over time, the roles gradually shifted. Now, after only 3 months, we switch back and forth effortlessly.
Just as the war-room is not mandatory, neither is pairing: anyone can "throw a pair-exception" and state that they need alone time. No harm, no foul. That's critical as well -- especially since there are
those days when one of us is irritable or that the common mental thread is just not there.
Write the tests first? Really? Come on....Everyone thinks that test-first sounds good. When you are sitting in a large group at a Java conference, it's an easy sell. It's modern and fashionable. However, when you actually are working on a project and want to impress a new client site with your productivity, it is
extremely difficult to write a test first. Especially if there are no existing tests for the old functionality. Often, the "real" code is right there in the editor and the new changes are seductively beckoning you to come up to the room.
It's perfectly obvious what we need to do! Just edit this method and....Gah. Thankfully, when working as pairs, one of the pair will act as the angelic conscience who says "tsk tsk"and waves a finger at the wayward, lustful programmer. Though grudgingly, the tests are written.
And it works. This is not news, but writing tests with JUnit is
fun. That damn green bar is just like getting a row of limes on some kind of Turing Slot Machine. It is an electrochemical buzz, broadcasting to our dopamine receptors. But it also changes the mindset for developing the "real" software. The game turns into this for the pair:
- Who can come up with the next "interesting" test that exercises the old functionality? (e.g. what if a string parameter is empty? what if something is null?)
- Once the test-suite is complete for the old code, what are some new tests for the new functionality? Again, there is an unspoken, fun competition to see who can get the next "meaty" test.
- As the new tests are written, the "real" code is written. Because of the priority inversion (i.e. test first), what was once so seductive can actually seem a bit dreary! Let's keep thinking of tests so that I can see that pretty green bar.
- Recently, we use a code-coverage tool, Emma, to check on the coverage of the tests. Even more green bars! Bliss.
When combining all of these aspects, I have never seen such high productivity with such a low defect-rate. This really works.
The moral of the story: most of us sample items from the TDD cafeteria, but only the things with which we feel comfortable. With serious expenditure on infrastructure and the dev process, my client site has really offered a full-blown buffet. Having tried some of the more exotic, challenging things on the menu, I gotta say: I'm a believer.