Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This question already has an answer here:

I used to pride myself with the high quality of the code I delivered. Today I made a mistake that wiped the grin off my face. It was a null reference exception caused by a hasty fix to an edge case that was caught during testing. I didn't have proper unit tests and I didn't regression test after making the fix.

So my question is, what do you do to force yourself to follow best practices? I know you should write tests (unit, integration, acceptance, etc.) and run them to validate any changes. But when the pressure's on and you're rushing to put out a fire, how do you keep yourself focused and sticking to those best practices? Physical exercise? Religious TDD?

share|improve this question

marked as duplicate by Jim G., Frank, gnat, Martijn Pieters, Kilian Foth Apr 9 '13 at 8:04

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

Best way to stop making mistakes is to stop trying. Problem solved! – Mayank Apr 30 '11 at 7:57
It's called experience, and that is what you got from the above situation. You now know that hasty fixes are dangerous! – user1249 Apr 30 '11 at 8:36
"The difference between experts and rookies is that the experts realize their mistakes sooner." ;) – Macke Apr 30 '11 at 10:20
Physical exercise, good sex and TDD cannot hurt. – Job May 1 '11 at 4:00
up vote 7 down vote accepted

When I do a mistake or fail something, I try to learn more about it. The possible consequences and the possible solutions.

Learning more help your (lizard) brain remind the mistake scenario and prevent you from doing it again.

When you'll face the same situation again, you will feel stress and you will remember what you did in the past and you won't do it.

If you do a mistake and there is no consequences (or you don't learn about possible consequences), you won't be sensitized to it. Therefore nothing will trigger you mind next time.

In others words, to remind something, it must hurt. This is valid for good things. To remember them, you must get pleasure.

This is a good example of how to use stress (mild fear) at your advantage. To learn.

share|improve this answer
Yes! This is kind of a meta answer, because I guess this question and all the answers are the "learning more" part. But this is the mechanism that I was looking for. When it comes down to it, I think we get cockier with age and learn to ignore our reptilian brain. It's strong in our teenage years, but the more we live and gain control over our environment, we realize we don't like the shame we feel. So we desensitize ourselves or run away from it. But basically, we have to use the shame in a constructive way. – Milimetric Apr 30 '11 at 11:03
when do you have time to improve when you hang out here all day? – Job May 1 '11 at 4:04

Your question is badly posed, IMHO. You're going to make mistakes, and lots of them, unless what you are coding is trivial. The important thing is to find them early.

But if you want to write code that is as free of errors as possible on the first run, I would suggest thinking about inputs, outputs, and invariants. Break things down into the most atomic methods/functions you can and think about the entire range of inputs these functions might receive. Put in some asserts that make sure they receive only what they expect. Put in some asserts that make sure they return things only in the range you expect. Later on, if you can find a way to gracefully handle problems like this handle them gracefully. But at first, asserts are better than nothing.

Most non-trivial coding errors are caused by failing to consider a case. If your functions depend entirely on their inputs, and you carefully consider all possible inputs you will avoid a lot of those problems. In other words, anything you can do to make sure the cases are easily enumerable is a win, as long as you bother to enumerate them. IMHO, being good at exhaustively enumerating cases/making cases easy to exhaustively enumerate is the single most important skill a programmer can have.

You should also avoid mutating state where possible. This is an extension of the idea that global variables are dangerous. Unfortunately OO makes this a bit tricky, but you should still strive to be able to see how a certain value came about without having to think too hard about state. I want my functions to always do the same thing, given the same inputs. Anything that breaks that makes errors more likely.

share|improve this answer
+1 it's hard to phrase it right. I agree with what you're saying, but I meant more - how do you focus your mind to follow these practices. I'm assuming that you know the practices. Kind of like your parents tell you not to do something but you do it anyway because you're lazy and inexperienced. – Milimetric Apr 30 '11 at 4:16
How did you learn to not touch a hot wood stove? You touched one. How can you learn to make less mistakes as a programmer? You can take every mistake as personally as a burned hand, and try to never make the same mistake twice. You can learn enough about proving things that you can be sure that individual routines are correct (good luck proving a system correct.) You can then think about how to make systems in which correctness proofs (even intuitive ones) are useful. If you really care about correctness I would also suggest re-evaluating the currently fashionable OO paradigm. – T Duncan Smith Apr 30 '11 at 4:28
I'd also recommend Bertrand Meyer's book for more on preconditions and postconditions in a reasonably digestible format. I'm not crazy about Meyer in some respects, and I would urge you to take some of what he says with a grain of salt. But his discussion of inputs, outputs, and invariants is good. – T Duncan Smith Apr 30 '11 at 4:37
Of course, meta languages like LISP, Haskell, and SML are verifiable which is much better than testable. And more fun to write too. But C# is getting closer to the "more fun to write" part. Verifiable is going a little too far, I don't think it would make too much sense in a frantic business environment. But one thing I'd point out here is that making mistakes in a business environment is not ok. You cost people lots of time and money. I'm thinking a mixture of physical activity and limiting distractions can help reduce mistakes. – Milimetric Apr 30 '11 at 4:41
As a long-time CL programmer I don't think that my CL code is automatically more verifiable (whatever that means) than my Java code is. I do think that having done a lot of Lisp makes my Java code better, and makes me more inclined to write code that is provably correct. Unfortunately it also makes me very frustrated with Java ;). That aside, whether or not it is "OK" to make mistakes is a silly question. I have worked with some godly elite programmers, guys who just put me to shame, and they made mistakes all the time. It is important to catch mistakes though. – T Duncan Smith Apr 30 '11 at 4:54

When the pressure is on: slow down!

This may seem counter-productive, but it isn't. Mistakes will always be made. Mistakes are more likely when you are in haste.

When the pressure is on that is often because (some) client(s) can't continue their work/use of your software until a problem is fixed, or a problem needs to be fixed before the next version can be released.

All the more reason to take it slow(er) when the pressure is on. If only because the stakes are even higher than usual as the lashbacks (clients losing trust in you/your software) are more severe when you get it wrong.

So, whatever you do, when the pressure is on do not skip important steps.

Even if there is a manager panting in you neck. Just tell him to go away and let you do your job or it is going to take even longer. If only because (s)he is distracting you...

When we are faced with a situation that requires a hot fix because there is a problem that is preventing an entire company from using our software (which they have come to depend upon), we no longer "ship" the hot-fixed version until it has been tested by QA. We feel it is better to have them wait another couple of hours or even a day, than to provide a "solution" that needs to be fixed again... (and again, and again...)

I can't remember his name, but I think it was a Japanes person/philosopher who said that the busier you are the more often you need to lie down for 5 minutes and consider what you are and will be doing next. I have found it helps me keep my priorities straight and prevents me from chasing after someting that doesn't contribute to my goals. I have found it also helps in my software development to keep me focused on the end-goals (user must experience value from our software) and not get caught up in a "let's put out this fire as quickly as possible" rush.

share|improve this answer

You can't. You will make mistakes, and the only way to mitigate them is to have some else review your work.

eXtreme Programming preaches this for just this reason.

On my team I don't let developers commit their own work to the mainline repository, someone else has to respond to a merge request, review the affected files, test the changes and then commit the code to the public mainline repository. That means two people have to drop the ball and both make mistakes. In theory it can still happen, in practice it hardly ever does.

Decades ago I worked in the publishing industry, nobody expects copy writers to write perfect copy, nobody expects typographers to typeset perfect copy with no errors, that is why we had an entire department dedicated to proof reading other peoples work. It is the only way.

share|improve this answer
This is great for a world that has accepted extreme programming. Unfortunately for us, we do not live in such a world :) – Milimetric Apr 30 '11 at 4:17
You don't need XP for this, @Milimetric. You just need to have a peer review process: A writes the code in a separate branch, and B reviews the code and merges it into the mainline. You do need discipline though, and peer pressure to keep to the process, especially when you're up against a deadline. – Frank Shearar Apr 30 '11 at 8:19
Yep. But at the risk of sounding like a broken record, sometimes you get orders from up above to stop reviewing each other's code and to just jam stuff in. I guess the answer there is just to say no. I'm BAD at saying no! :) They should make a movie called "No Man" – Milimetric Apr 30 '11 at 10:57
@Milimetric: then the people that should care about mistakes don't, why should you or anyone else below them care. Time to polish up the resume and find a better place ... – Jarrod Roberson May 1 '11 at 5:46
Well, if I moved every time someone else made a mistake, I'd reach speeds that violate Einstein's equations. Honestly, I prefer to take care of my own stuff and find ways to work in any situation. I do leave when there's ethical violations beyond my control. – Milimetric May 1 '11 at 13:16

I think it is important to take the physical aspect of working into account. Making sure you are well rested is important. If you stay up later then usual to get extra work done you should sleep late the following day. Otherwise, sleep deprivation will lead to more mistakes and a slower pace in the long run.

I have also found that taking a physical break (like going for a walk outside) can be very productive. You can get a fresh perspective when you just think through your code instead of actively working on it. Solutions to bugs and improved ways of doing things will usually pop into my head during those times.

share|improve this answer

First of all, you need to accept that human do mistakes. That's why we as programmers trying hard to create applications that reduce the tendency of human to make mistakes. So, if you did a mistake, that's totally fine, and look toward the solution to fix the mistake you've done.

After that, here are my suggestion.

  1. have a checklist, based on experience, write down things that you normally do. When doing a project, use this list as the guidelines and remember to check it as done when it's done.
  2. Get someone else to test for you. Different people see a system from the different angle, so more bugs and mistakes will be spotted before it launch.
  3. always make backup of your production files whenever you rollout something new, this will allow mistakes that you did reversible.
  4. share your implementation or codes with your co-workers, or have a peer review.
share|improve this answer
1) use an issue tracker. 2) Yes, assuming you have your own tests- make sure there is another layer of testing though 3) use version control and check in often so you can roll back to find bugs, etc. 4) Yeah, sunlight makes for good code. Never hide it until it is "better." – T Duncan Smith Apr 30 '11 at 5:43
+1 for checklists. Ben Laurie suggested not to long ago that we need a checklist for vetting the designs of security protocols after we saw yet another subtle session fixation bug. Checklists are like test suites in that they flesh out with time/experience, but they can be applied at many stages including the all important design and deployment phases. – Mike Samuel Apr 30 '11 at 17:25


are good for this sort of thing. Think of it as a regression test for your behavior.

share|improve this answer
I love checklists. They are amazing and make my life more simple – user2567 Apr 30 '11 at 7:16

As you say, you know the answer is unit testing. If you automate the test process as part of the build, then you cannot avoid running the unit tests, no matter what the time pressure is. Having the testing automated in this way mean you don't have to "force youself" to remember to do it, it will happen anyway.

Not running unit tests is not a shortcut, it does not save time. It may mean you check in code faster, but the finish line is not a checkin, it is a completed project and the quickest way there is to run unit tests on every build.

And don't beat yourself up too much, the bug was found in testing, you got a minor bit of embarrasment and it's now fixed. Really not a big deal.

share|improve this answer
Oh, it's a big deal, believe me :) +1, good point on the build server, we just haven't had time to set it up (same reason for all the pressure) – Milimetric Apr 30 '11 at 10:59
Not just the build server, you should do a local build on your machine before any changes hit the build server, and you shoud run unit tests there too. – Steve Haigh Apr 30 '11 at 17:00

I have sightly different perspective. Remember that you are working on top of a 'system of work' all the time. Whether it is unit testing / TDD, checklists, or anything else, they all form part of your system of work. Now, every time you make a mistake you also expose a flaw in the system of work. Of course you can always say to yourself to be more mindful, but I have found a lot of success in immediately searching for a fix in the system and setting out implementing it instead of just telling myself to do it right next time. Whether it's scripting a previously manual step, or agreeing on a slight process change with your team, you might be surprised at how many solutions to problems can be found in simply tweaking the system, which includes all tools, processes, team members, methodology, management, etc.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.