A couple of people responded to a recent tweetstorm with a request that I list all the necessary technical skills referred to. I can’t do that, but I can write this article to mention a few.
Some related articles are:
What Agile Approaches Demand
The “Imposing Agile” article above does a decent job of describing what I think is necessary in an Agile software development organization. Putting it a bit differently, to be doing Agile software development well, we need to accomplish at least these simple but definitely not easy things, from the beginning to the end of building a product:
- In the first week of the product effort, produce a running, tested, working Increment of the product. This will be incredibly low on features, but will contain something of the essence of the product.
- Every week thereafter, update the Increment to include whatever new behaviors were selected to be built. Behaviors are customer-visible and selected by the team’s business-focused planning process. (This could be a Scrum “Product Owner”, real users, a joint team process, whatever. It is always focused on user capability, not architecture or design or the like.)
- The Increment must always be fully tested. By this I mean that it’s tested well enough that we know with near certainty how many defects there are in it. And we keep that number near zero. When it goes above zero, we fix the defect, and we fix whatever aspect of our process allowed the defect to be put into the product.
- The Increment’s code is always clean. Names are clear and consistent. The code contains little duplication or cut-and-paste code. It is made up of modules (objects, functions, …) that are highly cohesive and loosely coupled. As the code drifts away from clean, as it always does, it is nudged back into place.
- The Increment’s design and architecture are always as good as we know how to make them. As they drift away from what we now see as needed, we nudge them back into place.
The above may seem daunting: I hope it does. But it is also what is required to do even the simplest Agile method, Scrum. Don’t believe me? Read the nice short Scrum Guide and think about what delivering the Increment really means.
It means that every week (or two, if you’re wussies) you deliver a real, tested, working, growing version of the product that is releasable, with high quality throughout, and since you have to do it every week (or two) it will need to be good both inside and out.
The Skills Required
The above list is simple: basically we have to build a near-perfect mini-version of the product in the first week, and keep it at high quality in every regard, while adding more and more capability to it, week after week.
That’s simple, but it’s not easy. It requires a lot of skill to do it, and most of what we need to know isn’t taught in schools and we won’t pick it up reading Learning Python in 180 Days. It’s just not in that kind of book.
What would we have to do to accomplish that list above? Let’s think together.
- Story Slicing: To have a working version in a week, we have to slice off a really tiny bit of product functionality, so tiny that we can fully complete it in a week.
- Test All the New: Since defects have to be at or near zero all the time, each new slice must be fully tested as well as developed, in the same week.
- Test All the Old: But since we’ll be improving the design, removing duplication, putting all the capability where it belongs, we need to test all the previous features, not just the new ones, every week.
- Evolve Code, Design and Architecture: We may or may not have all the design and architecture in mind in the first week. My guess is, we won’t. But we must always have good code, design, and architecture, which means the actual code quality, design quality, and architecture quality must always be improving, as the product’s capabilities grow.
Those few items add up to a lot of skill. Programmers do not come out of the box knowing how to do those things. Most of the people I know on the technical side of Agile have been learning to do those things better and better, for years. This stuff is simple: it isn’t easy.
There are many practices and tools that help us to do those simple but not easy things. The generic terms for the best ones I know of today include:
- Test-Driven Development: TDD is a practice where, as we program, we write a tiny test for the next tiny bit of capability we’re about to build, we make sure that the test doesn’t already work, we build that tiny bit of functionality, we make sure that that test, and all our other tests, now run, and then we improve the code quality right on the spot, again making sure the tests all run. Since we’re doing this every few minutes, all the tests need to be automated, and very fast.
- Refactoring: The code, design, and architecture improvement step above is called Refactoring, and it refers to improving the design of the code, not by massive rewriting and replacement of huge tracts of code, but by small incremental changes that nudge the design slowly back to where it needs to be. If each behavioral change we add is small, usually the design implications are small, and it’s fairly straightforward to refactor back to good. Sometimes, it’s more difficult.
- Acceptance Test-Driven Development: To me, ATDD is mostly a technique for communicating between the business-side stakeholders and the technical-side. It does offer an extra layer of confidence in the product, but for me the communication aspect is more important. ATDD is kind of an outer layer of tests, outside TDD. We’re building customer-focused behavior, and we use “acceptance tests” or “customer tests” or “product tests” to describe what we’re going to do, and then to show ourselves and our stakeholders that the system really does what we intended to do. Since the product and its design are growing, we’ll want to check all the features all the time, so these tests, like the TDD ones, need to be automated.
- Rich Knowledge of Architecture and Design: This isn’t so much a practice or tool, but it is critical, so I’ve added it.1 We’ve mentioned Refactoring, which is how we evolve a [mostly] ever-improving design and architecture while building the product incrementally. To do that, we need to know the difference between good architecture and design and not-so-good. We need a rich pool of architecture and design options in our bag of tricks, ranging from very simple options to the more complex and rich options that we may need as the system grows. One never knows too much about the quality of architecture, code, and design. One does, of course, need to apply that knowledge smoothly, incrementally, little by little.
- Continuous Integration: We generally find that in order to have working tested product weekly, we really need to have working tested product all the time, notching it forward daily or even every couple of hours. There’s a whole panoply of tools and techniques to support continuous integration.
It goes on and on …
The above are generic names for some of the main technical ideas we need to master. You can find articles on the internet and books to study. You can find on line courses to take, and there are in-house courses available as well.
Behind these short simple lists, we find a lifetime of learning. And since good Agile Software Development requires working software all the time, these are a few of the skills that are absolutely required to do Agile well.
Thanks to James Shore for the reminder about this missing element. Are there more? Let me know. Of course there’s an infinity of things we need to know: these are my top favorites. For those of James and Diana Larsen, see the Agile Fluency effort. ↩