In the software development lifecycle there are two types of milestones that occur on the path to delivering working software. Let’s take a look at each.
The first is simply a marker to indicate that we have complete a major task or phase of the project. When this type of milestone occurs we automatically move on to the next phase or step of the project. Examples of this type of milestone are “Development Complete”, and “Show and Tell”.
The second type of milestone is one in which an evaluation is made. Based on the result of that evaluation the work either moves forward or some form of rework is required. Examples of this type of milestone are “Code Review”, “Functional Testing”, and “User Acceptance Testing”. It is this second type of milestone that we will focus on for this blog entry.
This rework that is be caused by failing an evaluation is pure waste as we end up with work moving backwards in the value stream. But what can we do to eliminate this waste?
As a coach I help teams realize that it is important to eliminate practices that have the potential to cause rework and replace them with a different practice that keeps work moving forward. What follows are some examples of practices that eliminate or minimize the waste caused by rework.
I am not going to discuss the practices in detail because that is not the purpose of this post. I want this post to point out and help you to identify some milestones that have the potential to cause rework.
Anytime we review code there is the possibility we will find something in the code that causes concern. Usually, when we find this code issue the correct course of action is to refactor the code that caused the concern. This is a blatant form of rework which is waste. The waste is more profound if the code review takes place after testing is complete as the code will need to be tested again after the refactoring is complete.
The practice that we use to eliminate this waste is pair programming. We have two programmers working on the story at any given time and switch pairs often. But how often should we switch pairs? The only study I know of that compares the effect of switching pairs at different intervals is one conducted by Arlo Belshee. In his study he found that the team achieved best results when the switched pairs every 90 minutes.
When I coach teams I usually have developers begin by switching pairs once a day and then move on to twice a day after they are comfortable with the practice. From that point the team decides the frequency of pair switching. I have not yet worked with a team that switches pairs every 90 minutes but I look forward to trying it sometime. Switching pairs twice a day has three developers collaborating on a story that is finished in a day and five developers collaborating on a story that takes two days. This constant review should catch any issue of concern that would normally be found during a code review.
Testing software after development is complete is another example of waste experienced by most software development teams. When defects are discovered developers need to drop what they are working on in order to address the new defect. Also, testers typically stop testing the story with the defect because they know they must retest everything after the problem is resolved.
I like to catalog most defects that can be found in testing in one of five categories. They are:
- Functional Defect
- Regression Defect
- Missed Requirements
- User Interface Issue
- Funky Stuff
Functional defects occur when the story does not do what the product owner specified. The way to eliminate this waste is to write and automate the tests prior to development. I call this acceptance test driven development. The developers must be able to and should frequently run these tests on their local development instance. The goal is to find functional defects while the developers are writing the code and thereby eliminate the rework.
Regression defects are when you change one area of the application and it breaks functionality in a different area of the application. The way to eliminate this waste is to have our functional tests run frequently – at least once per day and more frequently if possible. If you do not have your entire application covered with automation then this will be a manual effort. This manual effort should decrease as the number of automated tests increase.
Missing requirements are a very common problem. The solution to this type of waste is to ensure that the acceptance tests are understood by the product owner. The product owner should be able to state that once all of the acceptance tests run successfully the story is finished. Requirements that are discovered after development should be written as new stories.
User interface issues are when the visual aspects of the application do not match / meet the reviewers expectation. The first challenge is to come up with one person that is responsible for the visual appearance of the application. This might be the product owner or it might be the usability expert on the team. Once this person is identified they must be available to the developers during development. The developers should engage this UI person throughout development and ensure that the story does not leave development until the UI is reviewed and verified.
Funky stuff is the totally unexpected errors that occur from time to time. I do not have a good solution to find these types of things ahead of time. Exploratory testing after development is a good way to discover these issues. It is best if this happens as close to story development completion as possible.
Performance & Load Testing
If we find a problem during performance or load testing we have the potential for significant rework. The solution to this problem is to perform these types of tests early and often. If you can run these tests daily then when you find a problem the delta to research to find the problem is very small.
The goal of the post is not to detail out a set of practices but instead to point out a pattern you can apply to help you eliminate waste in your development process. We must first identify milestones/practices that have the potential to cause rework. Next we need to identify a way to substitute another practice that keeps us moving forward.