This experience report outlines technical lessons learned over a several year period across several projects within an organisation which aggressively applied most of the agile practices with much success. The success, however, was not been achieved without challenges and lessons learned along the way. This paper outlines the interesting observations we made while trying to turn the agile dials to eleven. Our starting assumption when we began this journey several years ago was that productivity and quality were opposing forces; you had to trade one off against the other. However, after turning the dials to eleven, we now believe that you can much more of both than we previously thought possible. In fact, we believe that applying the practices outlined in this experience report allow both much higher quality and higher productivity than traditional development.
The financial organisation running the projects discussed in this report has been doing agile for more than 4 years across many projects. This report however is focussed on the experience of about 30 developers across several projects over the last several years. The code-base across these projects includes 10’s of thousands of tests and 100’s of thousands of lines of code.
Each project maintains 100% coverage of all production code with no duplication and stringent metrics across the whole code-base. At times these goals were hard to achieve but with tool support enhancements and practice, these goals are now not only attainable but are attainable with repeatable and reasonably high velocity.
Each project has a coverage build which runs several times a day which breaks if coverage is not at 100%.
All production code is pair programmed using TDD. Some tasks such as build and tool enhancements are not paired. These practices have been extremely useful in producing a large consistent code base.
Each project has an evolved agile framework which reduces the amount of test code which must be written. In the early stages of writing tests the ratio of test code to production code was between 1.5 to 2 lines of test code for each line of production code. With the current test framework, the ratio is approximately 1:1.
When creating tests, test fixtures can be auto-supplied from Spring wiring, using auto stubs, auto mocks or domain instances. In addition, a range of helper classes for producing unique instances (of Strings, Integers etc.) allow test triangulation to be carried out without explicitly creating different test cases. This functionality is provided by a smart base test case class. It reduces code size and greatly increases productivity when creating tests. It supports both state-based and interaction-based testing styles. IDE support also exists for automatically converting between the expectations the mocking framework expects and code which the IDE can understand.
IDE support is used to create components which include interfaces, concrete classes and their tests; test classes are pre-initialised with code that checks class properties.
Method size is limited to 10 lines, class complexity limited to 5 and the number of parameters to any method is limited to 5. The excellent refactoring support in IntelliJ allows these requirements to be met with minimal reduction in productivity.
Facilities are in place to automatically check that nulls are not used in the code and that classes meet certain requirements. Different class properties are required and checked for different types of classes, e.g. domain data objects, components, immutable objects etc.
The Simian duplication detection tool is used to detect duplication and has a threshold level set to 4 lines of duplication. Any duplication breaks the build.
Because of the stringent metrics that have been adopted and the use of unchecked exceptions, sometimes third party packages are difficult to interface with. An auto-boundary mechanism is deployed to automatically convert a class from a third party into one that behaves nicely in respect of checked exceptions.
IDE support has been added into the IntelliJ IDE that knows about many of the conventions used within the project and automatically supplies refactoring and quick assist style mechanisms to convert non-conforming code into conforming code.
Some of the successes of the project that can be attributed to the agile technical practices include:
Aggressive agile developer practices can be successfully applied to a large project over a reasonable length of time, however good IDE support is needed to maintain high team velocity.
The talk will highlight the novel lessons learned including providing some metrics derived from the project. The paper will give some additional details and examples of applying the techniques.