The first step in achieving agility and technical excellence is to set up an infrastructure to support it. The infrastructure we will discuss here, an automated build server, is one of the most important aspects of agility because we can only consider a story as “done” when it is fully integrated into the build. Here are seven strategies for setting up the right infrastructure for Agile development:
1. Use version control for everything
I have not seen any development project in the past twenty years that wasn’t using version control. It is an essential tool for all development–Agile, waterfall, or whatever. But I’ve seen clients fail to version non-code files that are critical to their build (config files, scripts, stored procedures, etc.) and wonder why their releases were unstable. The fix is easy: version everything that your build depends on!
2. One click build end-to-end
When we are coding, we want to make it easy to run the build so we do it constantly, without thinking about it, several times a hour. Automate the entire build process so code is saved locally, compiled, automated tests are run, and if all the tests pass, the code is automatically checked in, built on the server, and more tests are run–all within a few seconds.
3. Integrate continuously
Continuous integration does not mean we have to ship product every sprint, but we could if we wanted to. Continuous integration is a key to making agile work. The tools are free, for the most part, and the value from the feedback you get is essential for agile development.
4. Define acceptance criteria for tasks
Every task should have well-defined criteria for acceptance to let you know when you are done. This can be automated with an acceptance testing framework such as SpecFlow, FIT, or Cucumber. This not only helps us know when a task is done, it also helps us not overbuild.
5. Write testable code
Once a team commits to automated testing, life becomes a lot less painful, not just for QA who doesn’t have to waste time regression testing, but also for developers who get instant feedback if an approach they are trying will work or not. But there is another benefit of writing automated tests, we begin to write code that is easier to test, which is ultimately higher quality than untestable code.
6. Keep test coverage where it is needed
As an idealist, I strive for 100% test coverage for my code, even though I know it isn’t always achievable. Because I write my tests before I write my code, I tend to have a high percentage of code coverage. However, for those who do not write their tests first, and have a requirement for a certain percentage of test coverage, it is not uncommon to write tests for the easiest code, like getters and setters, and leave the really hard stuff that needs automated tests without test coverage, which can lead to big problems.
7. Fix broken builds immediately
A working build is the heartbeat of a project. When the build breaks the entire project comes screeching to a halt. Do not let this happen, ever. Everyone who checks code in must be responsible for making sure it works. If checked in code breaks the build, it must be either fixed or backed out immediately.
A successful automated build is the key to knowing if your project is on track. Integration is often the worst part of a waterfall project and hides problems and true progress, so instead of putting it off to the end of a project, we do a little bit of it every day throughout a project because until a feature runs in the context of the rest of the system, it is not really done.