Life, Teams, and Software Engineering

Category: professionalism

Overtime as Failure

First, let me make myself clear.  This post isn’t focusing on voluntary overtime (though you should still consider the impact to your team, but that’s another post), it’s focusing on forced overtime in order to meet some deadline.  I consider this to be one of the worst kinds of failure.

Teams forced into this situation are typically faced with the worst of all possible choices.  Do we take shortcuts to get out on time and risk the quality issues that can come from that, or work long days and weekends, not have a life, and still likely introduce problems due to burnout?

It’s failure if you have to even ask this question, but let’s look at the choices anyway.

Keep Working 8 Hours

Hopefully this is the direction your management is leaning, but it comes with a cost.  In order to continue working at the same pace you must sacrifice scope or let the schedule slip.  Yes, personnel can change too, but I’m assuming that by the point you realize you need to make this decision that adding new people won’t get you to the finish line any faster.  Everyone must either accept the delay with the understanding that this is what is necessary to achieve the expected level of scope and quality, or strip out a few unfinished/untested features and move them to the next release (yes they should move to the top of your backlog).  This will let you release a working product of known quality without cutting corners.

Burn the Midnight Oil

Some people might not think this is so bad.  I think it’s one of the worst things you can do to your team.  What message are you sending when you’re forced into this situation?  To management?  To your team?  By deciding to work long hours, weekends, or even burning the midnight oil to put out the occasional fire (many of which were a direct result of those long hours and weekends) you’re sending the message to everyone involved that this is the new normal.
This sets a precedent and creates the expectation that all future situations like this will be addressed the same way.  Then the first time it doesn’t go this way (because you tried to do it the right way) you’ll catch flak about why your team is no longer dedicated to their job.  Do you really want to knowingly commit to 7-10s every few months?  Think of the children.

Evaluate Why

After you’ve made it across the finish line, you absolutely must evaluate how you got there.  How did you get into that situation to begin with?  Did the team commit to too much?  Did certain features take longer to implement or test than the team estimated?   Did the team not consider testing costs?  Were there a lot of unknown unknowns that crept in?  Maybe some other part of the process caused the schedule to drag?  You need to answer these questions in order to avoid this type of situation in the future.  

Don’t Go There

This is one of those cases where the best answer is to avoid asking the question in the first place.  Pull things that would normally be done at the end of a project earlier into the schedule.  Build your installer or deployment pipeline after the first couple weeks, produce system-level tests for each new feature you add (and make sure they pass before moving on!), do code reviews on a per-feature basis rather than monumental reviews at the end, etc.  The more frequently we do these things the better we get at them and it also has the welcome side effect of enabling us to be releasing almost all the time.
Remember, no matter what anyone tries to force you to do Quality Is Not An Option.  Be a professional and stand your ground.  This is a tough spot to be in, but burning your team out or torching the codebase with sketchy implementations will do more harm than good in the long run.
Comments are open.  I’m sure everyone has their own stories or advice to lend to this situation.  Let’s hear it!

Safe to Fail

Failure

Many people have what I believe to be a misguided fear of failure.  Fear of public humiliation?  Losing your job?  Harming your reputation?  Perhaps you’re a perfectionist who thinks they can’t live with failure.  Fear can paralyze and hold back our most talented people and when they aren’t putting forth their most daring work due to fear of failure or the consequences thereof something must change.

In the software development space failure is usually defined quantitatively as being over budget, under featured, behind schedule, or qualitatively as having poor quality, or in some cases that it just doesn’t feel or work quite right.  The period of time over which these failures occur tend to be on the order of months or years, usually to the detriment of everyone involved.  But could this have been avoided?  Were the signs there all along?  Hopefully teams and organizations that encounter these types of long running failures have the courage to ask these questions, answer them, and act on the answers, but I suspect far too many do not.

The fact is that failure at some, and often many levels is unavoidable.  Once you realize this, you can accept it and embrace it.  That is what we all must do: stop fearing failure and embrace it.  However, as with anything there are responsible ways of going about this, and not so responsible ways.  Should we seek to fail from the beginning?  No, that’s not the point.  The point is to recognize some failure, however small, (e.g. this code didn’t work, the schedule slipped, Bob just quit, etc.) and learn from it.  An unrecognized or ignored failure means that not only have you failed, you just missed a growth opportunity and have truly wasted your time.

But how can we encourage giving our people the freedom and flexibility to bring daring ideas to life without burning everything to the ground and descending into bankruptcy and code cowboy anarchy?  If my thesis is that failure is worse if realized over a long time period, the logical thing would be to decrease the time window in which the failure occurs.  There are many things you can do to shorten this window without being overbearing or invasive in day-to-day work.

With Projects

Make sure you are capturing real-time stats of where your group is on your roadmap relative to where you think you should be.  This will allow you to have a constant pulse on the general direction of your work.  An example would be a burndown chart at the project level or a similar tracking method at the organizational level.  At the project level I’m a fan of the Greenhopper burndown chart format.

In such a format if you find yourself continually over the ‘guideline’ you will want to find out why.  Maybe the team is overoptimistic with their estimates?  Maybe the team is being so rosy because they feel the real estimates wouldn’t be accepted?  Maybe estimates are being advertised as commitments when they were never meant to be?  Maybe the team isn’t the one making the estimates?

Asking these questions will allow you to course-correct over shorter time periods while keeping everyone happy and well informed.  This frequent analysis and adjustment can help prevent long running failures.

Day-To-Day

Wouldn’t it be great if we could compress realized failures into a single day instead of over several months?  For many things we do as developers this can be done; we have the technology.

Be sure to set up productive development environments with super low friction using tools like Autotest or Watchr.  Tools like this allow you to automate your workflow using simple triggers (like saving a source file) to do things automatically that you would otherwise have to break your train of thought to do.  For example, I have my Watchr scripts set up to build the project, run the unit tests, and then for an embedded project, deploy the same unit test harness to a real device and run it there.  This type of low friction environment allows you to focus on what you’re really working on and most importantly gets you that feedback more quickly.  It might only be 10-15 seconds faster, but it adds up.

At a less technical level, if you don’t know the answer to something, ask, don’t guess. Turn to the person sitting next to you and ask.  If they don’t know, keep going until you find someone who does, even if that means contacting the customer.  Ideally the person sitting next to you is your customer, but that’s a different post.  Your customer is invested in this and you owe it to them to avoid speculation where possible.  The longer you wait to get an answer, the longer that assumption lives in your system, which can start the timer on a long running failure.

With People

Make sure that you instill a sense of purpose and pride into your teams from the beginning.  Make sure that they understand why your organization is in business and the significance of what they are working on.  They must feel like they belong and that they are contributing to something of value.  Empower them to really own their work and they will exceed your wildest expectations.  An environment like this is also likely to have lower turnover than the alternatives.

Above all, challenge them, but don’t break them.  Make sure your management knows their people, their abilities, and their limits.  Better yet, make sure your people know their own abilities and limits!  Then have them placed in a team a little above their current abilities but not beyond their limits.  Make sure they have team members who can and will act as teachers and mentors who can also help reduce that risk of long running failure.

With New Ideas

Make sure that ideas are received and evaluated on merit.  A good idea shouldn’t be overlooked simply because it came from the new guy, the old guy, or the guy with a new idea every day (enthusiasm!).  Most importantly, make sure that your people know that this is how these things will be handled.  Be active about it, prove that you’re willing to put your money where your mouth is.  Don’t just put out a suggestion box, you’re all in this together and your people want to be as big a part as they can.  Let them.

Encourage, but constrain exploration.  If these new ideas have merit, charge the person who proposed it with running it down.  Give them a couple weeks to flesh out the idea.  If they show progress, give them a couple more weeks.  If they don’t, maybe it still warrants more exploration, or maybe it gets killed dead.  Either way, two weeks lost is better than 6 months or years, you’ve all learned something, and hopefully grown a little in the process.  Ideas that show promise can can grow into a great new feature, new product, or totally new venture.  Left unknown and unevaluated it’s nothing more than a missed opportunity.

You could also constrain a new effort on budget.  I get the impression from Fred Wilson at Union Square Ventures that this is how they do it.  Start them with minimal funding on a truly ‘lean’ basis and fund them further when concept, production, and execution show positive signs.  I’m positive this is an oversimplification, but hopefully my point is made.  I’m sure that a welcome side-effect of this type of constrained environment is that the team (or company, as it would be) will know how to operate within these constraints should the need ever arise again (money isn’t infinite after all).

Have Courage!

In conclusion.  Have courage, put structure in place to recognize impending failure early, empower your people, and above all, learn from your mistakes.  Failure doesn’t have to mean that it’s over, just that you can do things better, and we can always do things better.

Quality is Not an Option

While I’m hardly the first to talk about the “Tradable Quality Hypothesis” hopefully I can reinforce in some of my readers (all 10 of you :) ) that Quality is not an option.  You cannot choose to lower quality (or forego quality producing/assurance practices) in an effort to get more features “done” or to deliver work more quickly.  At least not for any realistic amount of time.  If you do this, you might as well plan the rewrite into the schedule now.

So What if I Do?

Immediately, you will probably feel little consequence from omitting a few test environments or writing up those features without any unit tests.  But I promise it will catch up with you.  Failing to test (at any level), continuing to use outdated tools (without a transition plan), and knowingly adding functionality of little to no explicit value contribute to decaying codebases where bug counts and cost of change increase, while overall velocity (i.e. the rate of value addition) will decrease.  If you skip testing it now, guess what?  You’ll end up testing it a lot more when those bug reports start rolling in.

Yes, you might get to be a hero; and everyone loves a hero, right?  Maybe.  But when a situation arises where heroics are necessary (e.g. long nights & weekends) just to hit normal commitments teams should not celebrate.  That person has just set the precedent for what your clients and customers will expect of the team from this point forward.  Resist the urge to be a hero and be a member of the team.  Pull each other up as best you can to pull it in at the end, but be careful not to introduce large variances that can invalidate your velocity for that iteration.

If your team is delivering less and less because you’re trying to catch up with bug reports you may never be able to make up that time.  This can not only harm your organization’s reputation, but your personal or professional reputation as well.  Considering that, is it really worth the risk?

How to avoid the hole and dig out

There are many ways to avoid getting into the position of deciding to trade off quality for short-term schedule benefits.

One word: discipline.  Be vigilant that everything you contribute is tested in multiple ways (unit, integration, UI, etc.), have as many people as possible review your work and provide input, and make sure those things keep happening.  Yes it’s hard and can look to the uninitiated as if you’re moving more slowly, but when that thing you just wrote inevitably changes next week you’ll appreciate putting forth the extra effort.

Next is education.  Everyone should understand (though not necessarily intimately) what goes into delivering functionality.  Establish your definition of done and make it well known.  Hang it on the walls.  Recite it at the beginning of each daily standup.  I don’t care how people remember it, just that they do.  Whenever something is untested, it’s not really done yet.

If you’ve found yourself in this unenviable position, the first step is to admit that you have a problem.  Seriously.  We’re all proud of our solutions but sometimes they need cut down and replanted.  There’s no shame in it, I promise.  There’s only shame in voluntary insanity (doing the same thing over and over again and expecting different results).

Next, come up with a plan of how to tackle what is most commonly the real problem: technical debt.  Technical debt is any sub-par component of your entire solution space.  This could be anything from an inflexible test harness, to untestable or scary to change code, to relying on outdated or unsupported software packages.  If it causes you pain on or disappointment on the development side, it likely falls in here.  Environmental or issues external to the team should be raised to the team’s manager (e.g. Scrum Master) for them to deal with outside the team.  You need to identify and manage this technical debt before there is any hope of a sustainable pace of quality and value.

Don’t try to make it perfect, just make it better.  Don’t feel bad about it, what worked for a team of 5 and 100000 lines of code may just not scale to a larger team or codebase.  Our products grow and so our development support infrastructure must grow around them.

Remember, we’re the professionals

It may give the higher ups warm fuzzies to hear that it can all fit neatly into a little box, but no one will like the feeling later.  We do them no favors by making commitments we know we can never keep within any reasonable standard of long term success.  Clients can and should set constraints on delivery and tell us what they want delivered, but it’s our job to define how best to get there.  I don’t tell other professionals how to do their jobs when I pay for their services, and I would hope they would advise me on the consequences of taking shortcuts, while avoiding them completely.  That is after all, why I’m paying them.  They know better than I do.

If there are doubts about making commitments, or about quality, don’t be afraid to tell your clients (or your teammates) the truth, or at least what you observe.  That’s what you’re paid for, speak up.  Ultimately, even if the clients don’t say so, I’m sure if you asked whether or not you should test this feature you just gave them they’d be scared you even asked the question. Quality is always a requirement even if our clients don’t list it as a deliverable.

Copyright © 2017 Life, Teams, and Software Engineering

Theme by Anders NorenUp ↑