This is an excerpt from The Art of Agile Development, Second Edition. Visit the Second Edition home page for additional excerpts and more!
This excerpt is copyright 2007, 2021 by James Shore and Shane Warden. Although you are welcome to share this link, do not distribute or republish the content without James Shore’s express written permission.
It’s October again. Over the past year (see Part II), your team has been working hard at developing its Delivering fluency, and now you’re a well-oiled machine. You’ve never enjoyed your work more: the little annoyances and friction you associate with professional software development—broken builds, frustrating bug hunts, painstaking change analysis—have all melted away. Now you can start a task and have it in production a few hours later.
Your only regret is that your team didn’t pursue Delivering fluency from the beginning. In retrospect, it would have been faster and easier, but people wanted to take it slow. Oh, well. Now you know.
As you enter the team room, you see Valeri and Bo working together at a pairing station. They both like to come in early to beat rush-hour traffic. Valeri sees you putting away your backpack and catches your attention.
“Are you available to pair this morning?” she asks. She’s never been one for chit-chat. “Bo and I have been working on the real-time updates and he said you might have some ideas about how to test the networking code.”
You nod. “Duncan and I spiked it yesterday and came up with something promising. Do you want to pair, or should the three of us mini-mob?”
“You can pair with Valeri,” Bo calls over, getting up and stretching. “I need a break from networking code.” He mock-shudders. “Even CSS is better than this.” Valeri rolls her eyes and shakes her head. “I’ll let you get settled in,” she says to you. “I need more coffee.”
Half an hour later, you and Valeri are making good progress on the networking code. A steady series of soft chimes comes from the workstation. Every time you save your changes, a watch script runs your tests, then chimes a second later to indicate if the tests passed or failed.
You’ve gotten into a steady rhythm. At the moment, you’re driving and Valeri is navigating. “Okay, now let’s make sure it throws an error when the message is empty,” she says. You add a test. Dong. The test fails. Without a pause, you switch to the production code, add an `if` statement, and save. Ding! The test passes. “Now when the message is corrupted,” Valeri says. You add a line to the test. Dong. Another `if` statement. Ding! “Okay, I’ve got some notes about more edge cases,” Valeri says, “but I think we need to clean up these `if` statements first. If you factor out a `validateMessage()` method, that should help.” You nod, select the code, and hit the Extract Method keystroke. Ding! No problems.
The sounds were the result of an experiment a few months ago. Despite the jokes about “Pavlov’s programmers,” they were a hit. Your team works in such small steps that, most of the time, the code does exactly what you expect it to. Your incremental test runs take less than a second, so the sounds act as instant feedback. You only need to look at the test runner when something goes wrong. The rest of the time, you stay in the zone, switching back and forth between tests, code, and refactoring, with the steady chimes assuring you that you’re on track and in control.
Another half hour later, the networking changes are done. You stretch as Valeri pulls the latest code from the integration branch and runs the full test suite. A minute later, it’s passed, and she runs the deployment script. “Done!” she says. “Time for more coffee. Keep an eye on the deploy for me?”
You settle back in your chair and watch the deployment script run through its paces. It tests your code on a separate machine, then merges it into the shared integration branch. Everybody on the team merges their code from and to this branch every few hours. It keeps the team in sync and ensures merge conflicts are resolved early, before they become a problem. Then the script deploys the code to a canary production server. A few minutes later, the deploy is confirmed and the script tags your repository with the success.
You saunter back to the task board and mark the networking task green. “All done, Bo!” you call. “Ready for some CSS?”
Welcome to the Delivering Zone
The Delivering zone is for teams who want to deliver software reliably.
The Delivering fluency zone is for teams who want to deliver software reliably. Team members develop their technical skills so that their software is low maintenance, easy to improve and deploy, and has very few bugs. Specifically, teams that are fluent at Delivering:1
1These lists are derived from [Shore2018b].
Release their latest work, at minimal risk and cost, whenever their business stakeholders desire
Discover and fix flaws in the production lifecycle early, before they can do damage
Are able to provide useful forecasts
Have low defect rates, so they spend less time fixing bugs and more time building features
Create software with good internal quality, which makes changes cheaper and faster
Have high job satisfaction and morale, which improves retention and performance
To achieve these benefits, teams need to develop the following skills. Doing so requires the investments described in the “Invest in Agility” chapter.
The team responds to business needs:
The team’s code is production-grade and the latest work is deployed to a production-equivalent environment at least daily.
The team’s business representative may release the team’s latest work at will.
The team provides useful release forecasts to its business representative upon request.
The team coordinates with its business stakeholders to develop in a way that allows its software to be maintained, inexpensively, and indefinitely.
The team works effectively as a team:
Developers consider code and similar artifacts to belong to the team, not individuals, and they share responsibility for changing and improving it.
All day-to-day skills needed to design, develop, test, deploy, monitor, maintain, etc., the team’s work are immediately accessible to the team.
The team pursues technical excellence:
When making changes, team members leave their software’s internal quality a little better than they found it.
The team actively responds to errors by improving the underlying system that made the error likely, reducing the probability of future errors.
Deploying and releasing is automated and takes no more than 10 minutes of manual effort.
No manual testing is required prior to deployment.
Team members are aware of how their skills affect their ability to accomplish the team’s goals and improve internal quality, and they proactively seek to improve those skills.
Achieving Delivering Fluency
The practices in this part of the book will help your team achieve fluency in Delivering zone skills. For the most part, they center around simultaneous phases.
Most teams, even Agile teams, use a phase-based approach to development. They may work in iterations, but within each iteration, they follow a phase-based approach of requirements analysis, designing, coding, testing, and deploying, as shown in parts (a) and (b) of the “Software Development Lifecycles” figure. Even teams using continuous flow tend to develop each story through a series of phases, using a swim-lane visualization to track progress.
But Agile is inherently iterative and incremental. Each story is only a day or two of work. That’s not enough time for high-quality phases. In practice, design and testing get shortchanged. Code quality degrades over time, teams have trouble figuring out how to schedule necessary infrastructure and design work, and they run out of time for testing and bug fixing.
To prevent these problems, Extreme Programming introduced techniques to allow software development to be truly incremental. Rather than working in phases, XP teams work on all aspects of development incrementally and continuously, as shown in part (c) of the “Software Development Lifecycles” figure.
- Adaptive Planning
- Incremental Requirements
Despite being created in the 1990s, XP’s testing, coding, and design practices remain state of the art. They yield the highest-quality, most productive code I’ve ever seen. They’ve since been extended by the DevOps movement to support modern cloud-based deployment. Together with incremental planning and requirements analysis, these techniques allow teams to deliver high-quality software regularly and reliably.
The practices in this part are based on XP. If you apply them thoughtfully and rigorously, you’ll achieve Delivering fluency. They’re grouped into five chapters:
The “Collaboration” chapter describes how to build software as a team.
The “Development” chapter describes how to incrementally build, test, and automate.
The “Design” chapter describes how to incrementally design code.
The “DevOps” chapter describes how to deploy software reliably and at will.
The “Quality” chapter describes how to create software that does what it's supposed to.