I attended a talk by Vandana Shah while at SD West 2008 that had a different perspective on transitioning to Agile. Most discussions on Agile focus on teams in the initial stages of a project, not after several years of code has been written. In the short term the costs of adding legacy code appear cheap, but in the long term become increasingly expensive in terms of maintenance and QA costs. The basic approaches to reducing this cost later on, by investing in your code now is to reduce complexity, increase test coverage, introduce best practices (coding standards for both code and unit tests), and as a result reduce the number of issues that make it to the QA cycle and production.
Unit Testing (Adding tests to legacy code)
So where do you begin? Start by adding tests to cover existing functionality in your product. The product is stable and in production, so start covering it with tests. There are two types of tests
- High Level – these are the tests that ensure the system does what it is supposed to, protects the business logic. These tests allow us to confirm that the functionality the user expects from the system has not been broken by any additional changes. These tests cover the bugs that will be the most likely to occur
- Low Level – these are the tests that cover individual pieces of logic, the small units that make up the high level tests
You should start with high level tests, these are the tests that offer the most business value. It is important to capture the overall functionality of the system with tests first when dealing with legacy code, since these are the tests that will provide the least hindrances to future refactoring.
Teams need training on Unit Testing and often they demand it (especially when it comes to refactoring existing legacy code to get it into a testable state). Document it on the wiki and update it regularly!!!!! Providing this training early on prevents a mess that needs to be cleaned up later.
Switching to Agile
Switching an existing team with a legacy application over to Agile requires a different approach then starting Agile with a new team working on a new application. It is a mistake to take the “All or nothing” approach to SCRUM, the “We must do it all now”. Agile in this type of environment should be introduced in a slow incremental approach where each new process is brought in one at a time, refined in the retrospective, then as that process stabilizes another is introduced. So the cycle is “Start small, test, refine, add more”. This approach may feel like a slower change, but often can make the transition significantly easier. Switching a teams entire process all at once, can lead to frustration amongst the team and loosely followed processes.
Problems with Large Projects (Code size)
Often developers will change their development process just based on the size of the existing application. For example, you have a very large project, it is very slow in your IDE tool, you want to use a refactoring tool, but are unable to because of the size of your project and how slow the tool runs on the project. So what happens? The team does not use a refactoring tool. This is a mistake that misses focusing on the core issue: The project is too big, it needs to be broken up. It is also a hindrance to TDD. Quick feedback is extremely important for TDD, long build times and slow running unit tests end up hurting this process. Developers do not want to wait for the tests to finish, so will write more and test later.
Regular Software Cleanup
Make time in each sprint to not just write unit tests, but to also remove dead code and duplicate code as part of the step of adding those unit tests.
Testing and QA
Allow automation to happen over time, DO NOT force it. Establish the right processes first, everytime those processes get ironed out, QA will see common areas that can be easily automated, then you can move in that direction.
One approach discussed to introducing Agile methodologies into an existing team was called “Piggy Backing”. Do not introduce a new process all at once, just introduce new items to the existing process slowly overtime, piggy backing on what the team is already doing. The team will evolve to where you want them to be and often get their quicker, with far less pain and less resistance from the team