Estimation is inherently hard. We all know that. There is a multitude of blog posts and articles on the internet explaining why i estimating time needed for software development is hard, and you can read those at your leisure.
In the ReQtest team, we regularly get our estimates wrong, and we’re OK with that – that is the nature of estimates, after all.
Sometimes we get them really badly wrong. And unfortunately it lies in the nature of software development estimates that when they are badly wrong, they’re wrong in the same direction: actual effort exceeds estimated effort.
Estimating the effort you need to put in
The explanation is simple: there is a limit to how much faster you can do a task, but there is no upwards limit on how much longer a task can take compared to your estimate.
If you estimate that a task will take you 3 days, then the best you can do is get it done in no time and save 3 days. But the worst you can do is spend infinite time on it. In practice you would probably abort your efforts after beating your head bloody against the wall for a week or two, depending on the importance of the task.
As a team, it’s tempting to dismiss cases of massive underestimation as one-offs. But after seeing enough of them, patterns will emerge that you can try to take into account in future estimations.
Dealing with new UX designs
One thing that, in our team’s experience, we tend to underestimate again and again, is major new UX design.
A new page that resembles existing pages is not so hard: a form with labels and textboxes, a few buttons, and we’re done. But when we have to create an entirely new kind of workflow, it always takes longer than we first think. We do something, try it out, realize it’s clunky, rework it, get feedback from other team members, rework it again, realize we need to fit another component somewhere, rework it again, etc.
How do we avoid this? We separate design work from development.
In the past we used to do UX design in parallel with writing code for the new feature, fitting the entire feature into one sprint. Now we do the design in one sprint and don’t start coding until we have a finished prototype. We also time-box the design and prototyping work. This has helped us avoid rework and led to fewer surprises.
Integrating unfamiliar third-party components
Another kind of task that has a tendency to exceed estimates is any kind of integration with unfamiliar third-party components. We’ve skimmed the documentation, we’ve had a look at the API, maybe even done a prototype, and now we think we have a reasonably good idea of how to do code the actual feature. But when we start doing it for real, all sorts of complications can arise.
The API doesn’t match the documentation.
The error messages are cryptic.
Features that we thought we understood turn out to work differently than expected in subtle but important ways.
Investigating these things can take a long time because unlike in normal coding work, the component is a black box, so debugging is by trial and error. Maybe support tickets need to be raised and discussed back and forth, which introduces additional delays.
Third time’s a charm
We’ve run into this problem twice in recent years.
In both cases the feature ended up taking at least three times as long as we initially estimated. Twice is enough to be a pattern, but not enough to give us much experience to learn from, so we still don’t have a better way to estimate this kind of work. The third time, whenever that comes, we might simply triple our estimate!