If you are reading this, you probably already know what WIP is, but just in case you don’t, it stands for work in progress. WIP is a crucial component of Agile development, describing the stories or tasks that are (you guessed it) in progress. A general goal with any Agile project is the keep the WIP down. Doing so helps prioritize getting work done, limiting all of those “almost there” stories that linger for just a bit too long.
There are already a number of methods for keeping WIP down, such as WIP limits that restrict how many stories can be in progress at any one time. The method we employ on our team is to only have a single story in progress at any time.
This may seem overly restrictive, but as a developer, every story spends most of its time with me. The more in progress stories I have on my plate, the more divided my bandwidth and attention become.
However, the shortcomings of this approach become obvious as soon as a story is sent off to testing. I am now sitting, twiddling my thumbs, waiting on testing to tell me the feature was perfect, and there was no reason to wait. With this in mind, it is tempting to send a story off for testing and immediately start on the next story.
“But wait, there’s more,” says our tester, who has somehow managed to find something wrong with my code. I now need to back-pedal, pause the new story, and fix the outstanding issues, thus wasting more time context-switching than I would have simply waiting.
From here on, let’s assume I have convinced you that keeping the WIP down, even to just a single story, is the best way to manage a project. Here are five methods my team uses to keep the WIP down:
1. Prioritize Your Bottlenecks
Inevitably, there are bottlenecks with any project or team, and they need to be prioritized. From a developer’s perspective, there are two types of bottlenecks: me or someone else.
If the bottleneck is me, prioritizing work to remove a block helps everyone. I no longer need to worry about the outstanding task, and the team can move on with the story.
The other bottleneck is more challenging because I am not managing or prioritizing the work of the “bottleneck resolver.” In this situation, I have found two techniques that facilitate quicker resolution.
The first is clear, concise communication defining the bottleneck. The more I can clarify the bottleneck’s context and resolution, the less time is needed for the resolver to understand and deliver.
The second is to stay responsive. If a “resolver” has a quick question or clarification that I can help address and resolve, the whole process moves more quickly.
2. Refine the Backlog
After doing everything I can to facilitate a quick resolution of the bottleneck, the next step is to work through and refine the technical backlog.
When stories define a feature or scenario that needs to be implemented, but leave the specifics of implementation up to the specific developer, the developer can help by outlining the requirements and tests needed for the implementation. This forethought primes the story to fit into the larger picture, without any context-switching to start the implementation.
This also provides an opportunity to reach out about potential future blockers. Sometimes, you can get the resolution process started before an issue becomes a bottleneck or blocker.
3. Bump Up Tests
Once I update the backlog and define everything (within reason) that needs to be defined…now what?
Test-driven development is crucial to any successful application. As stories are developed, good practices dictate writing a test before implementing the story. However, functions and features not captured by the original test can be left uncovered, creating a technical burden that needs to be resolved in the future.
Taking time to bump up tests while you wait on a story can shore up these oversights. Using automated test coverage calculation helps to pinpoint areas that lack tests and can use improvement. Future developers on the project, possibly even me, will be thankful for the robust set of tests.
4. Review, Reflect, and Refactor Code
At this point, I have refined all of the backlog, created every test, and I am still waiting. Now is a perfect time to revisit older, dirtier code to review and reflect on how it was written.
If a developer says they have never written slightly off or just working code, they haven’t been programming long enough. With downtime on a project, going back and reviewing this code can provide better insight on ways to improve everything from code consistency to performance.
During this stage, it is more important to review, reflect, and comment on code than it is to change it. Reflecting and commenting will help future maintenance, without changing a working application. However, there are cases where adding a bit of testing to verify a change is merited to reduce or remove any slightly off code.
If I’m still waiting, I like to reiterate these methods. First, it is crucial to go back to the bottleneck and verify there is no more information needed or updates that I could apply. If there are other conversations about scheduling and prioritization of work, now is the time I will bring the bottleneck to my project lead’s attention.
Inevitably, there are blockers that can not be resolved quickly and stories that need to be put on hold. In cases like these, it may be crucial to break a story up to isolate a blocker or re-evaluate how work is getting done.
If at this point, no progress is resolved, I will work down the list, further refining backlogs, adding testing, and reviewing older code. Beyond this, it may be necessary to start an additional story, but it is clear that I have done all of my due diligence to keep the WIP down.
There will always be bottlenecks in a project. Hopefully, I have provided a couple of useful tasks to keep you busy and provide positive long-term effects on a project. I would love to have feedback or thoughts on other tasks you use while you wait in the comments.
As my delivery lead would say, “You have to keep the WIP down. That’s how you get the Guccis.”