Thursday, March 28, 2013

Tim's 5 Observations About Estimating

People spend a lot of time and effort to improve the accuracy and precision of their estimating.

We don't do that anymore.

It turns out that agile teams, once they've established a reputation, don't need a lot of estimation skill and many teams around the world operate happily without making estimates at all, since they always work on the thinnest slice of the most important feature at any point in time.

Now that I'm a greybeard programmer, I've come to believe five somewhat-controversial things about estimating.

Highly accurate estimating does not make your customers successful.


I'm always concerned about wasting a lot of time and effort (ie generating waste) in order to become good at something that does not make my customers more successful.

If I reduce the standard deviation of my estimates by half, it doesn't mean that my eLearning students will be any more capable of learning or that the materials are any more clear.

How much of my time is well-spent not helping my customer?

Estimating doesn't really matter (for production).


Regardless of whether you estimate 200% high or only 25% of the actual time you need, the same amount of work is going to be done this week.

Every software development group has to do with planning and estimating and budgeting for some period of time (annually, semi-annually, quarterly, etc). We have to provide some estimates to make that happen, but very few groups are actually doing the work they had planned a half-year or an entire year ago.

Again, it doesn't have to be exactly right, it just has to be credible enough to acquire appropriate resources for getting the job done.


Estimating is done at the wrong time.


The cone of uncertainty tells us that we know more about the time and cost of a feature after we've finished it than before we start. When we are just proposing a new feature, we have the least knowledge we will ever have about how we will do the work.

We are unsure of the skills we may need to develop, the topics we may have to learn, unaware of many of the issues that may arrive in implementation, and entirely unaware of the events that may distract us from the work.

The problem comes when people believe that the promise is the latest possible date that the product/project will be done, but they have argued for the soonest date with a non-zero chance of completion.

Further = larger.


Since work we must do further in the future are so uncertain, we recognize that we can't safely estimate those jobs now. So we add time. This is reflected in the use of fibonacci numbers for estimates, because size (and distance in time) magnifies the risk. Higher risk = higher estimates.

It just makes sense that we do not underestimate future work, since it is always easier to add more work later than it is to negotiate features out of a promise that has been made.

The other advantage of assigning larger numbers is that it suggests that the story/feature might need to be split into smaller, simpler, more obviously implementable pieces.

Teams can do five size-two stories in a shorter period than they can do two size-five stories. Smaller jobs are less likely to expand or have hidden complexities. It pays us to keep our estimated units as small as possible.


It pays to be safe.


Even though estimating can't be really excellent, and it doesn't really matter, and it's done at the wrong time, we often have to estimate (at least roughly) anyway.

We find there is a social effect to underestimating that is painful. The social effect for overestimating a little is pleasant, but for overestimating a lot it can be equally painful.

So we fall back on two  observations from Estimating Software Projects:

  • The shortest period with a non-zero chance of success is not an estimate. 
  • A good estimate is as likely to be short as long. 


Being safe, and not being too precise, seems to help when estimates must be produced. Considering how iffy estimates are, it might be better if you can change the way you work to not use estimates at all, or at least to not depend on them.









Waste = DOWNTIME

The title of this blog is more controversial in appearance than in reality.

DOWNTIME is merely an acronym to describe the 8 wastes:

  • Defects
  • Overproduction
  • Waiting
  • Non-utilized talent
  • Transportation
  • Inventory
  • Motion
  • Extra processing
This I found at wikipedia's Muda entry, and thought it might be worth kicking a link and a quick definition on the blog for those who might want to also use a mnemonic trick. 

Note that this is the 7 Wastes that are widely recognized, and the 8th waste of unused talent. This acronym doesn't tell you what to do about them, but that's what the kaizen event is about and we leave it to other experts to help you deal with recognized waste (for now).

Friday, March 22, 2013

Product Health Rules!

Dealing with product health is simple in theory.

You need to have a central build-and-test server and a repo that is treated as the central repo for the developers (in git, servers have no built-in roles). It has to be set up to run all the tests, whether they are unit tests, story tests (cucumber, etc), or what-have you.

Now, the thing you have to know is the state of your local machine, and the state of the build server.

When I say GREEN, I mean "builds and all tests pass."   When I say RED I mean that something doesn't build or did not pass all the tests.

The Rules


The rules in precedence order are:
GET TO GREEN. 
Green to green; anything else is obscene.
You need to know that your code is good, and the server's code is good, and you can push your code to the server.

"But wait", you might say, "there are states unaccounted for here. What about pushing green to red?"

"But Tim!" you may cry, "my code isn't the code that broke the build/tests! Why should I slow down when my code is okay?"

If you work all by yourself, you can probably afford a little slack here,. If you have a whole team in the same code base, or if you have many teams in the code base, then breakage affects everyone. The only sane way I know to manage product health is for everyone to follow the same simple rules in a disciplined way.

Rules Illustrated


Let's assume you have a largish team, or a few teams working together on the product, and these rules will be more obvious.







Green to green is great. You can pull from green builds, you can push your green code to the green build. Nobody gets frustrated, nobody gets hurt.







Can I pull from a green build when I'm in a "red" state? Well, it's possible, but it's likely to cause a lot of confusion as you try to find out what you've done to turn yours red.  You may end up merging over broken code and accidentally turn your machine green, but you'll never know what you did, quite.

Better to revert the local code so you're green, then pull the latest. Programming is complicated enough that we don't really need to make it worse.






Pushing to a perfectly good green build from a red local build? Obscene! It breaks the build and that's not good for anyone. It does happen, but it's bad. Usually, it happens when people don't know if their own build is green or not. I've done it myself, when I didn't run all the tests locally. I hate breaking the build, especially when I find it was preventable.


What about pushing from a green build to a broken build? Won't that just increase the balance of good code on the server side? It might even fix the build? 

Well, if you are the person fixing a broken build, it's fine. Otherwise you are getting in the way of the person who is trying to fix the build, and that's just rude. Don't make their job harder.

By pushing good code onto the broken build, you are slowing down the build's transition to green. Our first-priority rule is to get to green. You're in the way. Why not wait until it goes green, then merge, test, and push? 
  





What about pulling from a red build? You want to have the most recent code to start your next change, right?  Yes, but you will never be sure whether "red" on your box is referring to your error or the one you pulled from the main code line.  Worse, you might get used to seeing red, and stop reacting to errors on your own computer! Better to leave a red build alone.

Exception: if you are pulling from a red server to fix the build, you have the first-priority rule on your side.







Hey, if the build is already broken, what does it matter if I push more brokenness at it?  Once again, pushing to a red server will complicate the process of getting it to green. Someone may figure out the original problem, and then be totally confused when they merge in your new problem on top of it.

It won't do to get used to the idea of brokenness and then compound it. This is the famous "broken window effect" that psychologists talk about. It's the last thing our code base needs.

The Loophole!

Hey, we've found a loophole! If we never write tests, then our code is never technically red. All of the tests that exist continue to run green and we can check in as long as nobody else breaks the build!


Okay, mr smarty-pants, that gets you around the rules, but leaves you with unknown brokenness in the code. You don't really know that your code works, or that it will still work after merging with other people's code. 

By testing, you are reducing the period between the addition of a bug and the detection and removal of the same bug. You reduce the number of people who have to be involved. By not testing, you are saying that it's okay that your bug might be caught by external QA or by a customer in the field. You are even leaving open the possibility that it might cause greater issues by generating bad data that is used to subtly steer a customer's system into a more complicated and painful kind of failure.

If you're lucky, your error will last long enough to cost the company millions in customer service time, debugging, customer downtime, loss of reputation, and even product failure.

Or maybe you'll get away with it this time. 

Is the question mark really better than writing a few tests? I'm thinking that faking product health is no better than ignoring it. Besides, TDD is fast and easy when you get used to it. It is one of the fast, safe practices that build teams reputations.