Wednesday, May 14, 2008

A Practical Guide to Becoming Agile (on a latte-a-day budget)

Agile Software Development is so much a part of what we do in my company that many of us forget that parts of the industry have barely heard of it, much less scratched the surface.

While we are by no means experts on the topic (and many of the technologies/techniques we use have perfectly acceptable alternatives), I thought I would record how we got to this point for the benefit of others who may be interested in improving their own software development processes and need some ideas on how to make Agile work for them.

Interestingly enough, the company I worked for in 1999 was one of the most Agile environments I’ve been in, though none of us had heard the term at the time. It was a start-up company developing a transaction management platform for the real estate industry.

One of the senior developers I had the good fortune to work with had all kinds of crazy ideas I’d rarely seen implemented: collaborative development (pair programming), weekly code reviews, coding standards that make sense, etc. Additionally, the product manager, who I had followed from Houston to Indiana (having worked with her a couple of times and realizing that she was one of the most competent people I would ever work with), had similar ideas about having an on-site customer, making sure we were consistently and accurately gauging the value of feature requests to make the best use of resources. For those of you familiar with Malcolm Gladwell, maven meets connector and Great Things happen (not the least of which was their eventual marriage).

The Importance of the Agile Coach

Though we didn’t have a term for it at the time, Jason was what many Agile shops refer to as an Agile Coach: someone who is extremely knowledgeable about software development and has a passion for identifying areas that need improvement, researching alternatives, and proposing solutions. An Agile Coach constantly looks for the part of the process with the highest cost for the lowest reward and finds a way to improve that.

Finding an Internal Champion

Once we had an Agile Coach in place to convince all the people doing the actual work why we should be Agile, we needed someone to convince management and customers. This is the part where Agile often breaks down in typical organizations. People who have not seen the evidence of Agile’s efficacy often have difficulty getting past breaking down user stories, using points instead of time estimates, or why pair programming is not half as efficient.

We had the luxury of having a team that largely flew under the radar as a testbed for many of these practices. I cannot recommend highly enough finding a way to start small when implementing Agile. There are dozens (if not hundreds) of different Agile flavors. Find the one that makes the most sense for your team and organization. By implementing one or two techniques/practices/solutions at a time, we were able to assess what worked, gather evidence on why it worked, and present data on how much better it worked.

Getting a Real Source Control Solution

For anyone still working with SourceSafe, I empathize. Any source control solution whose standard operation requires a repair process is fundamentally flawed. Then there’s performance (local and remote), administration, functionality…

But I digress.

Switching to Subversion was one of the highest value, lowest cost elements of Agile we adopted. For one thing, it’s free. It’s been pounded on by the open source community. The performance beats the stuffing out of SourceSafe (particularly in remote development scenarios), and I shudder to think how we would accomplish the level of branching we do today with SourceSafe.

Implementing a Requirements Automation Framework

One of the more expensive and labor-intensive methods of failure we discovered was the waterfall method of requirements gathering. There may be situations where requirements need to be documented so extensively prior to development. Unfortunately, we consistently spent so much of our time correcting the documentation of requirements that had changed during the six to nine months it took to document them that we inevitably abandoned the documentation. “Oh, you can ignore that; the requirements changed and we didn’t have time to update all the documentation” was a frequently heard phrase.

Using fitnesse, we were able to more closely tie documentation of requirements to test plans. Instead of existing as disparate documents (and, yes, we tried all sorts of schemes to track the relationship between requirements and test criteria), the two co-exist in the same wiki format. Whenever a change in requirements is identified, it’s easy enough to change the test cases, since they are usually on the same page.

Using Test-Driven Development

For the traditional developer, learning to write tests before code is like learning to ride a bicycle…backwards…blindfolded. Some people take to it freakishly easy and make the rest of us secretly despise them as we work to master something that goes against all our experience. Having become accustomed to TDD, I can’t imagine writing code any other way. Before adopting the practice, I had made a concerted effort to limit the scope of whatever I was working on at any given time. I realized that a lot of the coding quandaries I got myself into were the result of trying to take on too much at the same time. And I thought I had really made good progress on this until I started really implementing TDD and realized how much smaller I could make that scope. Focusing on a test at time really brings clarity to the requirements and how I am trying to implement them. We use NUnit and TestDriven.net.

Frequent Builds

You’ve heard it before: “Works on my machine.” DLLs, folder dependencies, permissions…all ticking timebombs on a developer’s machine waiting to go off when you try to deploy the application elsewhere. Our initial approach to resolving this issue was a daily build. We used NAnt (supplemented occasionally with batch files, bailing wire, and duct tape) to script a teardown, retrieval from source control, build, and test of the system. This took a fair amount of effort to put together after the fact, so I recommend doing it as you build your application. It immediately paid dividends, as we found issues within 24 hours of being introduced when the nightly build was run and reported. It even became a contest amongst the team to see who could go the longest without breaking the build.

For many projects, a nightly build is sufficient. Since we were working on a custom event broker and translation engine to integrate various systems, we needed a little more. We implemented continuous integration using CruiseControl.NET. Now, each time a change is made, the solution is built, all smoke tests are executed, and the team is alerted to the result. We keep the continuous integration tests as minimal as possible while still being a representative test of the system’s functionality. Productivity is hindered if developers have to wait around for 30 minutes at the end of the day to make sure the changes they just checked in didn’t break the build.

There’s certainly more to Agile development than I’ve mentioned here, but this is a good snapshot of most of the technologies involved as well as the rationale behind them. I hope to post more detailed articles on the use of each.