Agile development is awesome – the immediacy of developing code that gets deployed, where users and developers get continuous feedback around what’s working and what isn’t, is a high that can become addictive!
It can also become a runaway railway car that hurtles your software into a morass of unmaintainable, inefficient and dense code, with developers jumping ship rather than ever, ever dealing with the final mess. This state of affairs is referred to as “Technical Debt” in the Agile community, and it afflicts all projects to various degrees.
Test Driven Development, or TDD, is the critical success factor to achieve Agile projects and a maintainable code base together. You can’t be Agile if you keep breaking code. It’s that simple. TDD, like Agile, is a way of working rather than an add-on of ceremony or process after the fact.
Testing needs to become something you plan and set up first, not last. It is only in planning all the possible outcomes that must be tested for, that you fully describe your likely problems.
The well-respected Martin Fowler, of Thoughtworks, says “experience shows that when supported with the right processes, tools and training, integrated testing speeds up the overall delivery of software significantly. Repositioning testing at the heart of software development not only builds in quality but also creates value by striving to prevent defects before they occur, enabling developers to get feedback in minutes and regression test results in hours, and allows business to adopt testing activities which are highly aligned with their goals.”
I can audibly hear you (or your development team) muttering right now about time: never enough of it. Testing takes time. Some things can’t be waived away, and I can’t tell you that it doesn’t take time. But I am telling you that it is time that you need to afford, because TDD is the factor that will make Agile a long term success for your organization.
Your development team needs to build a rhythm (or flow) around delivery. TDD assists in this cause, thereby raising productivity. It also obviously raises quality. In short, the only time problem is in the beginning, when teams have to learn to think and code their tests before diving into development.
Did I mention that I mean automated testing? The point about TDD is that you build up a library, or suite, of tests that can be repeated. When you can repeat your tests, you know that the last sprint hasn’t broken anything that is covered by the tests. When you have complete coverage, of all functions in your system, then you can consider your project a success, and your team world class!
Some programming tools make TDD easier, and encourage the development of tests as you code. In this case your team has no excuse for not writing the tests as they develop (or before).
If you are stuck with a legacy language where TDD is not part of the tool set, then you just have to work a little harder. At KRS, we have added TDD to our legacy projects by writing tests for each SQL stored procedure in the project. This doesn’t test the user interface, but it does mean that we can automate the testing of all the data manipulation, which is where the meat of the application logic often resides.
Now the strange thing is that TDD is easy to sell – every developer will agree that TDD is a great idea, and that when there is good test coverage they can see it saving them lots of time and effort. The “but” comes in implementation, and at KRS it has been the hardest idea to actually implement.
The challenges were the usual, around not having enough time, and resistance to change. Here are some of the ways you can address this:
- Time, and specifically deadline pressure, is the easiest thing for management to solve. Management usually sets the deadlines, and they need to explicitly make time for scenarios to be drawn up and coded.
- People are change resistant until they can see the benefits. Focus on the improvement in code quality and the reduction in bugs that will result from a thorough TDD implementation and your developers will naturally start to change.
- Build the TDD step into your definition of “Done”. Even better, build it into your “Design Done” stage if you can. Writing tests really should precede development, but we’ll take them at any stage rather than skip them!
- Measure and Reward the behaviour – set a test coverage target and reward your teams when they reach it. Make it a goal to reach a comprehensive test coverage on each project.
- Don’t let technology be an excuse. If your project doesn’t have built-in TDD support, come and talk to us at KRS about strategies you can employ to get most of the benefits with a bit of innovation.
- I’ll repeat myself, but it’s a good point to end on – TDD must be part of the way we work, and not an afterthought! Every part of your organization’s culture and behaviour must emphasize this.
About the Author
Lorraine Steyn is a founding Director of Khanyisa Real Systems, and a self-confessed nerd. KRS are Microsoft Gold Partners, who specialise in large database projects with high availability requirements. Khanyisa Real Systems are leading proponents of Agile project management principles.