“Done” is a surprisingly ambiguous word in software development. Back when I was in college I thought an assignment was “done” if it compiled and produced more or less the result I was expecting. Then I got a job in the industry :)

It turns out “it compiles” doesn’t mean much when you need to ship software that handles edge cases correctly and works in more than one browser and doesn’t throw exceptions when it’s used just slightly differently from the way I assumed it would be when I built it.

Another complication is that people use the word “done” to mean a lot of different things. I’ve heard people say “it’s done, I just need to test it” and “it’s done, I just need to integrate it” and “it’s done, it just needs to go through QA” and “it’s done, I just need to fix a couple of bugs.” It’s certainly useful to know what stage of development a feature is in, but none of those are done.

To me the only meaningful definition of “done” is “ready for production.” That is, is when the developer has tested the feature, QA has passed it, it’s been merged onto the production branch and any regression testing that needed to happen is done. When it’s ready to be deployed it’s done and not before.

That may seem overly picky but imagine how far off the rails things go when one person thinks done means “ready for QA” and someone else on the team thinks done means “ready for production.” If your feature (or project or report) isn’t actually done, your team lead needs to know that whatever other task they give you might get bumped if your original task comes back from QA with bugs. Obviously you should aim for bug free features but in reality things don’t always go according to plan. That’s why we have a QA department in the first place.

And to go on a bit of a rant, that example above of “it’s done, I just need to integrate it” is not even slightly done and is almost always a terrible idea. If you’ve developed something outside of the system it’s going to be a part of, you’ve exposed yourself to an enormous risk of terrible surprises. Sure, you’ll be fine if you just happen to have a perfect understanding of every little quirk of the larger system, but let’s be honest; you do not. Unless it takes a truly intolerable amount of time to compile the main system, you will actually save time in the long run by building your feature directly where it’s going to be used and just getting up for a drink of water or something while your project compiles. You’re almost guaranteed to have to compile repeatedly while you get your feature integrated anyway, so you’re really not saving any time by developing in isolation. Now, the plural of anecdote is not data and other people have probably had different experiences, but I have personally never seen that turn out well and strongly advise against it. Okay, rant over.

We like to pretend software development is perfectly logical and unambiguous, but you’ll actually run into issues like different definitions of done all the time. Even if you feel dumb doing it, it’s often really helpful to ask teammates exactly what they mean. A surprising number of the problems you’ll run into developing software are just miscommunications that could have been cleared up with a five minute conversation at the beginning of the project. Interfaces between client and server code in particular can be tricky. I’ve personally had to throw out work because I misunderstood what the client team actually needed and built something that was pretty close but not quite right.

Just because you think you know what your teammates mean when they say something as simple as “done” doesn’t mean you actually do. I’d love it if we could all agree what done actually means, but until then you can save yourself a lot of trouble by asking questions.