Agile pitfalls

Here are some suggestions for groups that may have recently adopted Agile methods. I am a long-time fan, but I have also seen Agile processes used to support SOLID waterfall habits.

§    What are Agile iterations for?

Someone who learns about Agile development entirely from new management practices may mistake the purpose of iterations. These are not simply milestones in a pre-determined schedule.

All Agile practices begin with "early and continuous delivery." At the end of an iteration, an updated functioning product can be tested and shared. Everything visible in the product does something useful. All features are reconciled with each other.

For each iteration you decide what will be the most useful additional functionality, given what you already have. Because you track your development velocity, you know how much progress is feasible. Because you always build on a stable product, you work at full efficiency.

Users help you refine the product throughout the development process, not just during a final beta testing period. When your schedule ends, then you ship the most useful product possible in the available time. You avoid an unpredictable stabilization period.

§    Iterative waterfall

The biggest pitfall of all, perhaps, is not actually iterating the priorities: [ Prioritizing_features.html ] . Do not attempt to plan every iteration for the entire project in advance. Otherwise, you might as well still be working with Gantt charts. You will lose flexibility and pass up unexpected opportunities.

It is misleading in Agile development to ask if you are ahead or behind schedule. You are trying to complete the most useful features of your system first. You have not finished a feature if it depends on functionality scheduled later. If you add features to an unstable system, then you are already behind schedule, because you have no idea how long stabilization will take.

§    Tracking velocity

Do not devote too much time to estimating project velocity -- what did you do, how long did you think it would take, and how long did it actually take. It is important to estimate velocity so that your product owners have reasonable expectations about what can be delivered at some future dates. You may also have other independent teams as internal customers of your work, who must adjust their plans accordingly. Within the group, you expect velocities to help you choose the right number of stories for each single iteration. If these are the problems to be solved, then collect just enough data to solve them. Do not collect data just because the process asks for it. Meetings should concentrate on clarifying functionality and customer priorities, not on tracking velocities.

You do want to know how fast you are making progress, so that no one promises too much, or too little. You may think your sales channel needs to know exactly what you are planning to build before you build it. I bet they would rather know exactly what they can count on (because it already works), what you plan to do next (likely to get done), and how fast you are moving. Maybe they would prefer an early version of the product that a customer can safely try out, however incomplete. They do not want a precise description of a product that then slips unpredictably for cleanup and feature triage.

§    Shorter iterations

Iterations may be too long. Agile and lightweight methods work best with short iterations. I prefer one week, but two weeks is probably the most common. Three weeks is stretching it, and four or five weeks is no longer an iteration, but a mini-project.

When iterations are short, there is less need to estimate velocity perfectly. If some tasks were too big for the previous iteration, then you will try smaller ones for the next.

§    Distributing chores

Too many developers may be developing subsystems independently. I think it essential for at least two developers to understand and feel comfortable with everything checked into the system. Instead of deciding on one developer for each task, always find two. That might mean fewer tasks get assigned each iteration, but you are likely to see more tasks actually get done, with less rework later.

When developers share the design and implementation, no one is critical path any longer. It is much easier to redistribute work as necessary. If someone runs out of tasks, or needs help, it is a great chance to share some expertise.

If you use a tracking system, then make sure you can assign a task to two owners at once, to encourage pair programming.

§    Do not misuse metrics

Management should not use Agile software to monitor programmer productivity. Some programmers may then compete to show progress on a larger number of stories, breaking into unnecessarily small tasks. This does not help the planning of the project. Worse, this accidental metric could work against collaboration. If you want to know how someone contributes to a project, ask them and their coworkers. It is hard to hide in a genuinely Agile project.

§    Staying Agile

With shorter iterations, tasks become more granular and easier to tell when they are complete. You do not need a long meeting to plan them out. You will actually measure velocity more frequently, with less effort, and get better at it.

Long or predetermined iterations (mini-projects) add inertia. It is harder for architects to adjust the overall design of the product. You may have a remarkably well-defined workflow, but be careful that it has not gelled too fast. Habitual processes may force you to identify big chucks of functionality for many iterations at a time. You then commit to substantial designs before your representative users have a chance to respond. Flexibility is lost.

Instead of using big iteration meetings to solve design issues, you can identify the right people to handle those designs in the next short iteration.

§    Doneness

Iterations should concentrate on user stories, not implementation details or development tasks. Stories invariably evolve during an iteration. Is the user able to solve the problem he wanted, though maybe not as anticipated? You want to take advantage of clever implementations that could not be anticipated when the story was originally conceived.

Sometimes an eighty-percent solution is simpler and more elegant, with more complicated use-cases delayed to a later iteration. Sometimes you can add more functionality than you remove. Everyone should encourage this sort of flexibility. Stories should be revised, split, and morphed as necessary.

On the other hand, an implementation should never pretend to do more than it actually does. A broken solution is not acceptable on any level. If the application blows up for certain cases, then disallow and hide those options. Make sure that you do not allow broken features to improve an arbitrary velocity metric.

§    Technical practices

Many popularizations of Agile methods avoid any prescription of technical practices. Scrum, for example, concentrates on project management and scheduling.

Here are some warnings about this emphasis from Agile leaders: ,

Metrics for progress and "burn rates" cannot neglect stability and efficiency for everyone.

For example, I still never see enough unit tests in code. I would use a code coverage tool like "cobertura" to see how much of code is actually being tested automatically. Without proper test coverage, continuous integration becomes impossible. Tests define what the code does and how to use it. Tests allow developers to share work on code: [ Unit_Tests.html ]

A project reaches full velocity when the environment supports continuous integration. New features can be completely reconciled with a fully functioning system. Programmers can safely update their code from the repository at any time. Tests allow programmers to refactor and clean up the code without fear of breaking anything. Dead code disappears. Every line and feature is useful.

§    Refactor your processes

Remember that every management process carries a cost, in time and effort. If you add a process to solve a new problem, then also try to remove a process for a problem that no longer exists. In programming this is called refactoring.

Bill Harlan, 2008-2009

Return to parent directory.