It can be difficult for me to estimate even small tasks accurately. To give you an example I wanted to write a small album generator during the last weekend. I thought it might take a couple of hours. I ended up working most of the weekend on it and it is still missing a couple of cool features to make it truly useful. And documentation requires work as usual.
Getting the core functionality done was quite fast. As usual you get some cool ideas during development and learn about new requirements. That made my initial estimate so wrong. It's acceptable in this case as this is just a hobby project at the moment. There is no commercial pressure and the hours are on me.
The project, stalbum, is available at GitHub. There's also a little starter thinger that helps you to build your own photo album.The situation becomes much different in a business setting, though. In this case you'll be making potentially a huge financial, and temporal, commitment. If possible, you should avoid too big deals and rather aim to cut them into separate parts treated individually. If estimating even small wholes can be difficult, can you imagine how hard it gets for something a magnitude or two larger?
The Risks of Software Estimation
|Homerun by Jeff Kramer|
There are a couple of factors working against us when we are doing our estimates. First of all there are cognitive biases. We might estimate that implementing a feature takes around an hour but forget that getting to that point requires some extra wiring.
It is also easy to forget about qualitative requirements. You probably want to maintain the quality of your codebase for instance. Development practices can make a huge difference. You could be reaching your goals early in the project but as technical debt catches up with you, you keep slowing down. If you are working on an existing project this can be a real risk. The quality of the codebase affects your productivity in a very concrete way.
Then there's the fact that there can be big differences in developer productivity. What might feel like an hour task to you could be three or more for someone else. This applies particularly if domain expertise is required. A domain expert might know exactly the thing that is required whereas a less experienced developer might have some research to do.
As you might know, there are three kind of knowns. Those we know, those we know we don't know and those we don't know we don't know. Yes, I know that sounded very rumsfeldian. It is the last one of these that kills estimates, though. A small new requirement might snowball through your project and cause additional work here and there. It all adds up to the overall effort required. Even the best estimate cannot take unknown unknowns in count reliably.
How to Mitigate Risks Related to Software Estimation?So we have established there is a lot of risk involved in this sort of work. How can we mitigate some of that risk? Are software estimates worth it even? I guess this must depend highly on domain and the clients you are dealing with. It doesn't just feel right to build a business relationship based on contracts like this. Maybe there are better ways that rely on something intangible like trust and success by iteration?
If the client won't budge and you don't have an alternative, there are some ways to de-risk your estimates. The most natural ways to me seem to be prototyping and chunking it up. Working on requirements in text format can be somewhat mind numbing. Once their amount reaches a certain limit, it becomes difficult to understand the whole. You might very well be missing some vital features. You will always miss a couple no matter what.
Start with a Prototype
|Wright Flyer by Tom Wigley|
So what if rather than working on requirements in just their text form you developed a prototype to complement them? This can be a viable approach especially in web development. There is a set of design and prototyping tools that allow you to achieve this quite fast. One benefit in working this way is that it bridges the estimation and development process in a nice way.
Of course after you do this it meanders into the realm of development but that might not be a bad thing. You'll get a better feel of things and their potential complexity after you have studied them technically a little bit. You will become aware of existing solutions and will understand how much custom work is required.
Speaking of prototyping it would be even better if you could involve client and users at this point. At this point it is very cheap to make changes so why not to make them? This will avoid some rework later on and you will be able to gain better results. The worst case scenario I can think of is that you agree with some set of requirements with your client and notice after the project that the users don't like the product and avoid using it. Technical success does not always mean you have reached business objectives.
Chunk It Up
|Cake by Alex|
Generally the larger your estimate is, the more room there is for error. If you have an individual requirement that takes let's say five hours to implement or more, you could consider chunking it up into smaller pieces. This forces you to think their relationships and how they relate to the whole system. You might open a can of worms accidentally this way but that is a good thing. You definitely don't want to open it during development.
There are some intangible tasks like user interface design that are difficult to estimate. It may be cleanest just to allocate some fixed amount of hours for that and hope it is enough. Prototyping can alleviate this risk as it forces you to make some decisions required.
Use the Right Tools
|Hammer by Ian Baker|
Even though it might feel like a good idea initially to gather your requirements in Word, Google Docs or something, try to avoid that. Things get very messy once you have to perform calculations. And they get messier when you start splitting up the work in iterations. Even a spreadsheet is better. There are tools for project management and estimation, use them.
In ideal case you should be able to import the requirements into your issue tracker and refer to them in commits. If you use a time tracking system, it would be excellent if you were able to hook that into the whole. This way you could actually see how close to the truth your estimates were. If you go beyond your estimates consistently, you know you are in trouble.
Leave Some Slack in the Schedule
|Sloth by Pierre Pouliquin|
Padding is one of those classic techniques that applies even today. It can be applied to the whole as a multiplier. The purpose of that is to counter those "unknown unknowns".
There may be some better practices available but having some slack seems like a good idea given things don't always go as in the ideal scenario. Software developers tend to be optimists. It is better to try to estimate a median scenario rather than minimal one.
Are you sure all of those features are actually needed? Try to come up with a sensible set of minimal requirements with your client and leave as much as possible optional. If there is time and money for it, those can be dealt with later after the completion of the main project. This way you avoid a death by thousand cuts. Small features add up quite quickly.
Software estimation is easily the hardest part of software engineering for me. It gets particularly hard when there's a lot of uncertainty involved. Even when you get to use your favorite tools and know the domain, your estimates can still go wrong. The margin for error is a magnitude or two larger when you don't have control over these factors.
If you look up the subject, you will find a lot of literature and techniques on it. The ones I covered here are something you likely come by intuitively. If you are working on a team setting, you could try to get multiple estimates from separate developers and have them justify them. That way you should be able to avoid some blunders and reach more realistic results.
Remember that time spent estimating is time that could have been spent developing. Perhaps you are better off developing a prototype which you can showcase to your client and users and then snowball the project from there.
If possible, try to avoid offers that feel too big as they come with a lot of risk. Of course if you are willing to accept the risk, go ahead. But do your best to mitigate it. Unless it might be a death march time for you.
I am very curious to know what sort of techniques and tools you use for software estimation. Do you consider software estimation necessary? How do you apply it in practice?