One of the great difficulties in software development is measuring progress on individual stories. It’s often difficult to provide an answer when asked how long something will take. Part of the difficulty is because software development does not have a linear path to completion; certain tasks may be more or less difficult than we expected and unknowns tends to be numerous. But also, we tend to consider done to mean done with the initial programming, often leaving out time to clean up, test, merge, etc. This can lead to underestimating time to completion if the additional steps are not accounted for, but it can also cause large variance between developers, depending on personal development style, unless the team has an agreement on what defines completion. This is the definition of done.
The definition of done is straightforward – it’s the list of criteria the team uses to determine when a story is complete. It typically includes most of the tasks we do anyway – create a pull request, have it peer-reviewed, and all tests pass. In my experience, most teams’ effort to create definition of done stops here, resulting in completing a checklist item that provides little value. But, if used properly, the definition of done can be the cornerstone of the team’s engineering practices.
The important part
The process of creating a definition of done is where much of the value lies. The discussion opens up an opportunity for the team members to discuss what development practices they value and why they should be applied universally. These can include additional requirements that are more individualized to the team’s situation and not necessarily copy-pasted rules from the internet. Depending on the challenges and situation of your team, you may find common recommendations not applicable. That’s completely okay. The emphasis is on the need to consider the team’s unique position and apply criteria that makes sense.
Since I am strongly focused on software quality, there are a number of checks I do on my own projects before I consider something to be complete:
- Code coverage – Code coverage is not the end-all-be-all of testing, but it can provide useful information about the state of it. High coverage does not guarantee tests are good, but low coverage guarantees existing tests are inadequate.
- Linting – Everyone has their own philosophies on code style, but more important is consistency. Linters help keep code consistent, while also ensuring no one has to waste time being the code police during reviews.
- Code quality metrics (smells) – SonarQube and other quality analysis tools are something I heavily rely on, because they find problems I never would have found on my own. Code smells are often ignored because they aren’t errors, but they can be signs of bigger issues and fixing them helps improve maintainability.
These are just a few examples from my own projects that could give you some ideas, because not every developer is going to agree on criteria and significant pushback can happen if team members start to feel the definition of done is going to become burdensome and slow down their work.
To not be a burden
There is one big reason why I’ve seen definitions of done thrown out – because it’s a burden. The definition of done can quickly become a significant burden to the team if it becomes inundated with too many steps, and team members may skip steps or only do them half-hardheartedly, the same way as when given a pull request that’s Just Too Big. There are a few things to consider doing to help prevent this:
- Automate everything – The more of our engineering practices we can offload to the computer, the better. This ensures we spend time doing the actual development, while minimizing the overhead cost.
- Do only what’s necessary – What is necessary is subjective, but if developers are often skipping a particular step, there’s a good chance it’s not necessary. Making sure the definition of done is created by the engineers themselves and not something forced on them by the manager will help ensure this is the case. The fastest way to do something is to never have to do it at all.
- Adapt the process – Make the definition of done a living document. Let it change as necessary to support the team. Agile emphasizes individuals and interactions over processes and tools. Make the process fit the developers and not the other way around.
- Enforce it – All team members need to be following the definition of done. Having some team members opting out will virtually guarantee the other team members eventually stop following it as well. If some team members are refusing to follow it, then perhaps it’s time to Adapt the process.
With the right mindset, the definition of done can be a valuable cornerstone of any team’s development practices. Creating one does not need to be a big affair, but it can allow for the team to create a list of criteria that is useful without being burdensome, to know definitively when a story is done.