Many people that I interact with seem to think that Agile == Scrum. While Scrum undoubtedly is one of the most prominent names among agile methodologies, there are other methodologies as well. One of these, and the first one that I personally got exposed to, is Extreme Programming (XP).
XP was pioneered by Kent Beck, Ward Cunningham and Ron Jeffries in 1990s. Kent Beck brought the principles and practices to public attention with his famous book “Extreme Programming Explained”.
While Scrum focuses on project management aspects such as planning, estimation, and monitoring, XP has an engineering focus. In this post, I am going to present a brief introduction to the practices of XP.
A desired feature in a system is called a story. Examples:
- As a sales executive, I should be able to enter a purchase order received from a customer
- As a training coordinator, I should be able to schedule a training program based on a purchase order
The collection of all the stories is called a Product Backlog in Scrum.
In Scrum, an iteration is called a Sprint, and two or three weeks is a common duration for a Sprint.
XP advocates one week long iterations. Teams that are new to iterative development often find one week to be too short a duration and difficult to manage. They may begin with two (or even three) weeks for an teration, and over a period of time, as they gain more experience and confidence, they may consider switching to one week long iterations.
The shorter an iteration, the greater the benefits. The code that has been built and tested goes into production earlier, thus the customer gets faster value from the working software, and the team gets feedback earlier.
Each weekly iteration begins with an iteration planning meeting, called Sprint Planning Meeting in Scrum. During the meeting, the customer explains the high values stories from the prioritized Product Backlog, team members break the stories and split them into smaller tasks, and commit to what they believe they can complete within the iteration.
Estimation is never accurate. During an iteration planning meeting, when the team estimates the stories and agrees on the scope, the team openly communicates the estimation uncertainty to the customer and accounts for it, rather than inflating the estimates on the sly.
They do this by letting the customer know that while the selected stories represent their best judgment about the estimated effort, and that they will do their best to complete all the stories they have signed up for, if some tasks turn out to be longer than expected, the relatively lower value stories may be dropped by them for the current iteration. These relatively lower value stories are known as slack.
For example, the team may tell the customer that while they are signing up for six stories, they are confident that at least the first four will be completed come what may, but the remaining two may need to be dropped if their estimates turn out to be ambitious.
All code that goes into production is written test-first. A developer consider what a class or a story is supposed to do, identify the scenarios for testing the code, writes test data, and automates the tests, before writing any code that implements the desired behaviour for a class or a story.
There are plenty of open-source frameworks for test automation, such as
- JUnit for unit testing a class
- Fitnesse for testing a story or an entire workflow
- Mockito for testing the behavior of a class without having to rely on the other classes that it depends on (by mocking the calls to those other classes and their responses)
It is not enough to test a class in isolation. From time to time, a change in one class causes another class to break. Therefore, integrate all unit tests in a test suite, and run the entire suite every time any code is checked in.
Continuous Integration :
There is no late integration phase in an agile project. All code is integrated all the time. The moment two classes are written, integration begins. Thus any integration issues get caught and fixed at the earliest.
The team dedicates a server for continuous integration. Using a source code management system, developers check in their code frequently (many times in a day) and run all the tests.
If the process for checking in the code, running the complete build and running all the tests is too long, the developers will avoid doing so frequently. But that would mean that the defects and risks will remain hidden for a longer period of time.
Automate the build process to make it fast. It does not have to be exactly ten minutes. The idea is that the developers should have the motivation to frequently check in their code, and run all the tests, so that any code change breaking somebody else’s code is caught as early as possible.
Avoid Big Design Up Front (BDUF). Don’t over-engineer. Rather, invest in design every day. Design close to when a feature is to be implemented. Keep evolving the design, refactoring as and when required.
When replacing a legacy system with an alternative, don’t wait for a big-bang, complete change. Move the workload to the new system gradually.
Any code that has been tested but not put into production is both a waste and a risk. Put new code into production every day. Automating the process of integrated testing is a crucial prerequisite for this to succeed.
While stories are built and deployed in weekly cycles, also use a quarterly cycle for high-level prioritization and planning, and for introspection. Use the quarterly cycle to decide the key themes or focus areas, not only in terms of the system functionality, but also improvements in the sevelopment process.
When a defect is found after development, don’t just stop at fixing it. Find out why the defect remained undetected earlier. What is the root cause behind it? What can the team do to ensure that such a mistake never happens again? Fix the root cause, and not just the defect reported. Learn about the “Five Whys” technique as a great way to get to the root cause of a problem.
Nobody owns any piece of code, and everybody owns all the code. If I have written some code earlier, and today you find an opportunity to refactor it, fix a bugin it, or add some functionality to it, you don’t have to wait for the owner of the code. Go ahead and modify it. Just take care that all the test continue to pass after the changes made by you.
All non-trivial code is written by two people working together using one computer. One person types the code while the other person also focuses on the code and provides strategic inputs such as better alternatives to the statements being written, missing test cases, refactoring, code reuse, code optimization and other desired qualities. The developers within a pair alternate the roles frequently, by sliding the keyboard and mouse back and forth.
Pairs are dynamic. No two people pair up for an entire project, or an entire iteration, or even an entire story. Pairs break-up from time to time and new pairs are formed by the team members.
Two heads are better than one. Thus pair programming improves the quality of the code being written. For example, if one developer misses out a boundary condition to check, the other developer may notice and correct. If one developer cuts corners with the agreed-upon coding conventions, the other one may nudge him to rectify. If there is code duplication, the other developer may suggest refactoring.
Pair programming also helps in better knowledge sharing as all pieces of code are seen by at least two sets of eyes, and (combined with the practice of Shared Code) eventually even more. So when a person leave the team, the risk of knowledge about some parts of the system also leaving through the door is greatly reduced.
Pair programming also makes the induction of new members to the team smoother. A new team members pairs up with others, starts understanding the domain, existing design and code, coding conventions, etc, and gradually begins to sign up for stories and tasks for the project.
Code and Tests
Code and tests are the only two artifacts that add value to the customer. Code, because it translates into working software. Tests, because these help you evolve and maintain a system with confidence. Everything else is secondary.
Single Code Base
Maintain only one code stream. Don’t allow multiple, parallel braches under development; these cause a lot of waste and risks. Branches for experimentaion spike solutions should be as temporal as possible; merge the successful solutions from these into the mainstream at the earliest.
Assemble a team with all the desired skills required for a project to succeed, such as developers, testers, UI experts, DBAs, etc. Create a sense of belonging and collective ownership in the team.
A team is most effective and productive if it is co-ocated. It eliminates communication barriers, fosters meaningful conversation, and thereby speeds up knowledge sharing.
What if you have a distributed team for a project? You then have to use technology and occasional travel to facilitate communication, but even then, within one location, get all team members to sit together.
Use the walls around the team area to capture and communicate interesting details about your project. Any interested observer should be able to get an idea about the direction of the project within 15 or 30 seconds. Examples:
- List of stories
- Task Board and Burndown Charts (from Scrum) that show the progress and status of stories and tasks
- Parameters that matter to the team, such as defect rate.
Working very long hours as a matter of routine is a symptom of problems relating to understanding of the stories, estimation, planning, etc. It is not a good solution to schedule slippages, except perhaps for a few days on rare occasions.
Working very long hours on a regular basis does not improve productivity proportionately; rather fatigue is likely to cause poorer quality of work, with a negative impact on productivity.
A project ends successfully, and then what do you do with the team? Send them back to the “pool”, and split it? No. Keep them together. Leverage on their collective strength for the next project. But…
As a team becomes more capable and productive, wean away some members from it and move them to form or join another team. They act as ambassadors of the best practices learned in one project and spread these to the others.
Real Customer Involvement
Make a real customer person available to the team for the duration of a project. The customer writes stories (with the help of a developer or a business analyst), prioritizes the stories, provides clarifications to the developers in real-time, participates in meetings.
Negotiated Scope Contract
Align interests of customer and supplier by working towards negotiating contracts that fix cost, timeand quality, but keep the precise scope open for ongoing negotiation. Reduce risks by signing a series of short contracts instead of a single long one.
Sometimes developers tend to build features that the customer did not ask for, but the developers believed that those will look great to the customer ( a possible example of this is the “I’m feeling lucky” button on the Google home page ). If more and more software is built on a pay-per-use model, the tendency for the developers to add fanciful features will be reduced.