15 August 2005

People are funny

People are funny. We know that smoking, drinking and eating too much are all bad for us, and that we need to get regular exercise. Here in Canada, the top New Year's Resolutions are always to lose weight, start exercising, and to stop smoking. I suspect that it's the same anywhere that such resolutions are made. Of course, those resolutions are usually broken.

So, I suppose that it shouldn't be a surprise that agile teams break resolution as well. Here are some practices and techniques that we know provide tangible benefits to the development process:
  • No production code is written without corresponding programmer tests

  • No code is checked into the source repository until all of its programmer tests are passing

  • Programmers work in pairs

  • Each story has at least one acceptance test

  • The acceptance tests are automated

  • Continuous integration, including the automatic running of the programmer and acceptance tests

  • When a build fails, the whole team stops to correct the problem

  • The customer is involved on a continuous basis

  • If there are multiple stakeholders in the customer organization, they speak with one voice (consensus)

  • The whole team is involved in the planning process at the story level – the customer provides the priority, and the programmers provide the estimates

  • When planning an iteration, the team only signs up for as much work as they were able to complete in the last iteration
At a current client, I'm part of a team of 17 good to extremely good people. A little over two years ago, we started using XP to build the first part of an integrated system. A very conscious decision was made to avoid stovepiping, and to integrate the data and functionality of several lines of business into a single system. The users would see different front-ends depending on their role, with a rich GUI client locally, and web interfaces for users outside of the local area and overseas.

When I joined the team in October 2003, the team was smaller, having only 10 people. They were actively pairing, tests were being written religiously, the customer was very involved, and the planning game was being used. We didn't have many tests for the GUI, but the system was still simple enough for both the programmers and testers to test manually. We also didn't have continunous integration, but it didn't seem to be a problem since the number of programmers was relatively low. The acceptance tests were manual, mainly due to internal political issues with obtaining a testing tool that didn't require the programmers to do the bulk of the work.

The first production release of the system took 6 months, and a second release was finishing up when I arrived, after 2 months of work. Further releases were already in the pipe, at about 2-3 month intervals. Even though we weren't doing the XP practices at 100%, we were certainly an agile team, and the customer was very pleased with the results.

Fast-forward to the end of the summer, 2005. The system has now absorbed 4 new lines of business, and has both the rich GUI and the web interface. This past week, we performed an emergency release to fix a couple of defects that only manifested themselves in the production environment. During the deployment, a quick test of the web application showed that one of the bugs wasn't fixed. However, it was working just fine the testing environment. After a few tense moments, we realized that the wrong WAR file was installed. This came about 10 days after the initial release had to be rolled back because of problems. That resulted in a few days of panic, leading up to a release that was deployed successfully, but had the above mentioned defects. All of this happened after a protracted development cycle of almost 9 months. The system had been unstable, and we spent about 6 weeks just fixing defects prior to the release. Our boss, who is usually very calm in the face of “issues" lost it, and rightfully so.

So what happened over the course of almost 2 years that took the team from agile to code & fix? During that time, we didn't just sit on our collective behinds, but actually did try to keep improving. Among the initiatives we undertook were:
  • Expanding our tests into the GUI code using tools such at HttpUnit/jWebUnit and HtmlUnit

  • Using Mock Objects to better focus the tests and reduce the dependencies on external classes

  • Using CruiseControl for automated builds, and to run our unit test suites

  • Investigate the use of Fitnesse for higher level testing at the integration and system level

  • Bringing in outside experts to coach us on testing and the use of frameworks like Spring in order to improve our code
Each of these initiatives was met with at least some enthusiasm, and people were initially using the tools and techniques. However, it seemed that invariably after about a month the enthusiam would wear off and the use wouldn't continue.

A prime example is the use of CruiseControl. Our team has a tradition of going out for lunch every Friday. We also had an unwritten rule that if anyone broke the build and had left for the day, they had to buy a round of drinks on Friday. With CruiseControl running, the incidence of broken build suddenly increased, and several people (myself included after I left too hastily one day without adding a new class to the repository!) had to shell out on Friday. The entire team suddenly became very careful about what they were doing, and we were the better for it! However, one day after a few weeks, one of the developers was hit with a second “round" in two weeks and protested his penalty. The rule of buying a round was repealed. In very short order, the build was breaking again, and as time went on people cared less and less. I was able to have CruiseControl execute our unit test suites, and to flag the build as broken when they didn't pass. Of course, the tests weren't passing, the build was failing, and the team decision was to disable the running of the tests (which I protested to no avail).

Another problem we encountered was that we had a tendency to focus on tasks rather than the completion of stories. We made a decision for one particular release to define the tasks, but only track the stories. We also decided that we wouldn't sign up for any more stories in an iteration than we completed in the previous iteration (Yesterday's Weather). The entire team made an admirable effort to do this, and we completed the release a few days early, and with very few defects during acceptance testing. Everyone – the team, our management, and the customer – was happy.

So with this success under our belt when we began the next release, what did we do? We lapsed back into a focus on tasks. The justification was that some people felt that they needed the tasks to be enumerated so that they knew what had to be done. I had no problem with this, but it was done at the expense of estimating that the story level, i.e. only task-level estimates were provided. The result was that we did indeed complete the tasks, but there was never any real determination as to whether the stories were completed. Thus, at the end of the iteration, we would find that we hadn't finished everything. With that happening, we also started overloading iterations with work, despite the fact that everyone knew we couldn't possibly complete it all in the time available. That “next release" was the one that I spoke of above, that was a near disaster.

It would seem that each time we found a practice that improved our results but took either some extra work or was simply different from what we had done before, we abandoned it. We broke our resolutions. We started smoking again, eating too much, and gave up exercising. We were feeling better and people were telling us how great we looked, but it took effort and time to keep it up.

We became lazy.

Back in the early 1970's, the Canadian federal government started a program called Participaction, which was intended to prevent us from turning into a nation of 30 million couch potatoes. One television commercial in particular received a lot of attention, in that it told us of how the average 60-year-old Swede was more fit than a 30-year-old Canadian. We were lazy, and it was going to cost us in the long run. It made perfect sense, and they were absolutely right. We needed to eat right and exercise more in order to improve our lives. The people behind Participaction also recognized that our health care system couldn't cope with the future costs of dealing with the various ailments that would be encountered as the result of our unhealthy lifestyles.

In the 30-odd years since Participaction was established, we have improved somewhat. Smoking nationally is at an all-time low. People are exercising more, although we still aren't as fit as that 60-year-old Swede. Essentially, we have moved from the equivalent of Waterfall or Code & Fix to a more agile approach. However, once we realized that it takes time and effort, we couldn't maintain an XP level of fitness.

So, are current agile methods such as XP doomed by the inherently lazy people that use them? I know that not everyone is lazy, and I'd certainly like to think that I'm not. So, perhaps there will always be a group of people who will have the necessary discipline to follow the practices, and those who either don't care or don't want to stay with them. Similarly, there will be a group of people who have the discipline to stick with the practices. I suspect that group is the same as those that would make the heroic efforts to save a project on a Death March.

I believe that a key question, then, is will we be able to sustain agile development practices when they move to the mainstream and are used by people who don't have the same motivation as we early adopters? More importantly, how can we make the practices so easy to use that anyone, regardless of their level of motivation, will follow them willingly?